zoukankan      html  css  js  c++  java
  • 30)django-ORM(元信息,级联删除,正反向操作,连表查询优化)

    一:元信息

        class User(models.Model):
            name=models.CharField(max_length,index=True)
            email=model.CharField(max_length,index=True)
            class meta:
                db_table="table_name"#定制表名,默认是app名_表名
                
    
                #联合索引
                index_together=[
                    ("name","email"),
                    #联合索引支持最左前缀模式(上面单独索引可以不用建立,但是要考虑使用场景。因为单独最后一个字段查询是不能命中)
                    #select * from where name="xx" 可以命中索引
                    #select * from where name="xx" and emial="XX"可以命中索引
                    #select * from where emial="XX" 不能命中索引
                    #所以这是有代价,最后一个不能命中索引
                ]
                #联合唯一索引,和联合索引又加了限制唯一
                unique_together=[()]
    
                #admin中显示表的名称
                verbose_name
    
                #verbose_name加s
                verbose_name_plural
    
                verbose_name_plural="上课记录" django-admin中显示的是:上课记录s
            
            
    
        django admin先经过modelform验证,通过了再到model

    二:外键级联删除(on_delete属性)

        class userType(models.Model);
            name=models.CharField(max_length=32)
    
        class user(models.Model);
            name=models.CharField(max_length=32)
            pwd=models.CharField(max_length=32)
            ...             (to="UserType",to_field="id")
    
    
        #delte from UserType where id=1 #原生sql直接报错
        UserType.objects.filter(id=1).delete() #默认也会把User表里关联的数据全部删除
    
    
        #某个场景可以删除,某些不能删除
            (to="UserType",to_field="id",on_delete=models.CASCAN)

     三:正反向操作

        #正反向操作
    
        #    一对多正向操作
        # v=User.objects.all()
        # for item in v:
        #     item.name
        #     item.pwd
        #     item.ut.name
        #User.objects.all().value("user","ut__name")
        
        # 一对多反向操作
        v=UserType.objects.all()
        for item in v:
            item.name
            item.id
            item.user_set.all() # 所有与之关联的User对象
        
        UserType.objects.all().values("name","user__pwd")#通过表名和_返回查询
    
        #上面通过表名反向查找,能不能换个名字
         ut=models.ForeignKey(to="UserType",to_field="id",related_name='b',related_query_name='a')#一对多正向操作,这个b可以代替(表名_set)反向操作.related_name='b',related_query_name='a'通过用不到,适用场景自关联
    
        # 一对多反向操作
        v=UserType.objects.all()
        for item in v:
            item.name
            item.id
            item.user_set.all() # 所有与之关联的User对象 ==item.b.all()
        
        UserType.objects.all().values("name","user__pwd")#通过表名返回查询 ==a_pwd

    四:性能优化(联表查询)

    #性能优化(联表查询)
        1)select_related
    
        #如果数据库中有10条数据,
        users=models.User.objects.all()#仅仅是用户表中的数据
        for row in users:
            print(row.user,row.pwd,row.ut_id)
            print(row.ut.name) #会再发一会SQL请求
    
        #上面相当于做了11次查询,效率不高。,如果外键很多,就跨表执行多次。
        users=models.User.objects.all().values('user','pwd','ut__nmae') #只执行一次。但是取到是字典。如果非要是对象。
        #再优化
        users=models.User.objects.all().select_related() 也是只执行一次,就都取到数据了。但是如果有些不需要跨表(多个外键的时候,只取一个一个外键),可以加参数(这里只能加与外表关联的字段)
        users=models.User.objects.all().select_related(“ut”)
    
    
        2)prefetch_related
        #上面如果联表联的多了也不太好,django提供prefetch_related
        如:100条数据和3条业务关联了
    
        users=models.User.objects.filter(id__gt=30).prefetch_related(“ut”) #这个不会做联表查询,会做两次sql请求。它会:
        #select * from user where id>30
        #获取上一步中所有的ut_id=[1,2,3]
        #select * from user_type where id in [1,2]
    
        上面都放在内存里面了。django会把两张表里的数据做自动关联。
        for row in users:
            print(row.user,row.pwd,row.ut_id)
            print(row.ut.name) 
  • 相关阅读:
    java实现第六届蓝桥杯格子中输出
    java实现第六届蓝桥杯格子中输出
    java实现第六届蓝桥杯循环节长度
    java实现第六届蓝桥杯循环节长度
    java实现第六届蓝桥杯格子中输出
    java实现第六届蓝桥杯格子中输出
    java实现第六届蓝桥杯循环节长度
    java实现第六届蓝桥杯循环节长度
    java实现第六届蓝桥杯加法变乘法
    深入研究java.lang.ThreadLocal类 (转)
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7892307.html
Copyright © 2011-2022 走看看