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

浙公网安备 33010602011771号