django mode3[性能相关]

实例操作

        class User(models.Model):
            name = models.CharField(max_length=32)
            pwd = models.CharField(max_length=32)
            
            class Meta:
                # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
                db_table = "tb1"
                
                #
                #就只会生成一个文件,此文件来记录索引信息:把name,和pwd设置为索引值
                #只能是最左前缀
                index_together = [
                    ("name", 'pwd'),
                ]
                
                # 最左前缀的模式:
                # select * from where name='xx'
                # select * from where name='xx' and email = 'xx'
                # select * from where email = 'xx' # !!!!无法命中索引 ,因为索引建立的是联合索引
                
                #联合唯一索引
                unique_together = (("driver", "restaurant"),)
                
                
                #在admin中显示
                verbose_name = “上课记录”
                verbose_name_plural=““上课记录””

一对多/一对一/多对多

#onetoone:在一对一基础上做的操作
#manytomany:在关系表里面是双向的ForiegnKey

一对多

        一对多:
                def func():
                        
                    return 5
                
                
                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)
                    ....         ForiegnKey(to="UserType",to_field='id',on_delete=models.SET(func))
                
                # delete from user where id=1
                # delete from UserType where id=1 # 报错
                
                # UserType.objects.filter(id=1).delete()
正向
v = User.objects.all()
                 for item in v:
                     item.user
                     item.pwd
                     item.ut.name

                 User.objects.all().values('user','ut__name')
反向
                 v = UserType.objects.all()
                 for item in v:
                     item.name
                     item.id
                     item.user_set.all() # item.b.all()

多对多 

如果一张表中有个ManytoManyField 那这个列不会再表中生成,它会帮你生成第三张表! 第三张表中保存了关联关系

       a. django创建第三张表
                m2m.remove
                m2m.add
                m2m.set
                m2m.clear
                m2m.filter()
            b. 自定义第三张表(无m2m字段)
                
                自己链表查询
                
            c. 自定义第三张表(有m2m字段)
                # 通过m2m字段查操作
                # 通过m2m字段 clear

数据库操作表

QuerySet中的方法  ----返回QuerySet类型所以可以 可以链式编程

如果垮多张表,那会影响性能,因为需要多次查询好几张表

性能相关 (select_related,prefetch_related)

select_related  #跨表查询  连表做了一次查询

原理:select_related() ,那就会一次性把所以与这个表关键的数据都拿过来了,避免了多次sql请求,selecr_related() 内能加参数,但是只能写与这张表关键的字端,例如forkey,多对多字段,用于帮我们做主动联表查询

            users = models.User.objects.all().select_related('ut')      
                    #ut是forekey ,里面的参数只能是连表的字段,比如manytomany,onetoone,forykey  !!!      
                    #这个会把跨表的数据一次性都拿过来,这样你使用循环的时候,就不会发起sql请求了
                    for row in users:
                        print(row.user,row.pwd,row.ut_id)
                        print(row.ut.name)
                        ##print(row.tu.name) # 如果没有select_related那就再发起一次SQL请求
prefetch_related  #性能高

原理:

prefetch_related(ut)。 是当查询一张的时候如:select * from user where id__gt=5 ,获取到所有的数据,但是在这些数据中如果有关联字段,假设是ut__id=[1,2]。那它就会拿着关联字段在进行一次查询,也就是select * form usertype where id in [1,2]
第一次查询表的时候,就把用户数据都拿到了,第二次语句查表的时候,就会拿第一次查询中所有的用户类型(这里的用户类型也就是forkey字段)来获取。那这样数据就都存在两张表了。都获取到后,django 就会把这2张表数据放在内存中,然后自动去处理,也就是拼接在一起,那你在循环对象取的时候,就会去内存中取。这样下来,只需要2次sql请求就能获取到数据
            prefetch_related 如果是跨表查询, 那prefetch_related会执行2次sql操作,把结果会放到内存中,
                    users = models.User.objects.filter(id__gt=30).prefetch_related('ut','tu')          
                    select * from users where id > 30
                    获取上一步骤中所有的ut_id=[1,2]
                    select * from user_type where id in [1,2]
                    select * from user_type where id in [1,2]
                    
                    for操作的时候会直接去内存中去取值,无需再去sql操作
                    for row in users:
                        print(row.user,row.pwd,row.ut_id)
                        print(row.ut.name)

Mode也有数据验证的功能但是比较弱

在创建module时,它的父类会预留一个钩子也就是clean方法,可以在clean中自定义验证
但是父的clean中,只实现了一个错误异常也就是validerror,你需要导入这个异常

 

        full_clean进行验证
            - 每个字段的正则
            - clean钩子

 

更多内容移步:Model:http://www.cnblogs.com/wupeiqi/articles/6216618.html

posted @ 2017-05-12 21:56  所有的梦想都画在墙上  阅读(177)  评论(0)    收藏  举报