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) 
  • 相关阅读:
    Entity SQL 初入
    ObjectQuery查询及方法
    Entity Framework 的事务 DbTransaction
    Construct Binary Tree from Preorder and Inorder Traversal
    Reverse Linked List
    Best Time to Buy and Sell Stock
    Remove Duplicates from Sorted Array II
    Reverse Integer
    Implement Stack using Queues
    C++中const限定符的应用
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7892307.html
Copyright © 2011-2022 走看看