model进阶(queryset,中介模型,查询优化,extra)

Posted jokerbj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了model进阶(queryset,中介模型,查询优化,extra)相关的知识,希望对你有一定的参考价值。

中介模型:

针对多对多关系,虽然可以自动创建关联表,但是需求是想要加入一些字段信息呢,这就需要自己手动建关联表了

对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。源模型的ManyToManyField 字段将使用through 参数指向中介模型

models

 1 from django.db import models
 2  
 3 class Person(models.Model):
 4     name = models.CharField(max_length=128)
 5  
 6     def __str__(self):            
 7         return self.name
 8  
 9 class Group(models.Model):
10     name = models.CharField(max_length=128)
11     members = models.ManyToManyField(Person, through=Membership) # through 指定关系表
12  
13     def __str__(self):            
14         return self.name
15  
16 class Membership(models.Model):
17     person = models.ForeignKey(Person) # 外键写上
18     group = models.ForeignKey(Group) # 外键写上
19     date_joined = models.DateField() # 需求添加的额外外键
20     invite_reason = models.CharField(max_length=64) # 需求添加的额外外键

注意事项:

 1     绑定关系的时候,与普通的多对多字段不同,你不能只创建 Person和 Group之间的关联关系,你还要指定 Membership模型中所需要的所有信息;而简单的add、create 和赋值语句是做不到这一点的。
 2     所以,你只实例化的时候,通过create来创建
 3     m2 = Membership.objects.create(person=paul, group=beatles,
 4         ...     date_joined=date(1960, 8, 1),
 5         ...     invite_reason="Wanted to form a band.")
 6 
 7 
 8 clear() 方法却是可用的。它可以清空某个实例所有的多对多关系:beatles.members.clear()
 9 # Note that this deletes the intermediate model instances
10 Membership.objects.all()
11 []

 

查询优化:select_related

select_related就是join表,当成了一个表的时候for循环每次循环只会是一次

 1 # 查询 主键等于2的文章的所属分类名称
 2 obj = ret=models.Article.objects.filter(nid=2) 一次
 3 for i in obj:
 4         i. category.title  # 每次打开2张表
 5 
 6 
 7 # ret=models.Article.objects.filter(nid=2).values("category__title") 一次数据库
 8 # print(ret)
 9 
10 
11 # select_related 就是join一张表,left inner join是一样的效果,以左边为主 right join,以右边为主    
12 obj_list=models.Article.objects.select_related("user").select_related("category").all() # 可以join多章表,也可以写在一个里面,逗号隔开
13 for obj in obj_list: # 
14     print(obj.category.title)。# 每次打开一张表

 

extra 函数

语法格式:

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

有些情况下,Django的查询语法难以简单的表达复杂的 WHERE 子句,extra可以指定一个或多个 参数,例如 selectwhere or tables这些参数都不是必须的,但是你至少要使用一个!

 1 select:简单查询
 2 queryResult=models.Article.objects.extra(select={is_recent: "create_time > ‘2017-09-05‘"})
 3 结果集中每个 Entry 对象都有一个额外的属性is_recent, 它是一个布尔值,表示 Article对象的create_time 是否晚于2017-09-05.
 4 
 5 article_obj=models.Article.objects
 6      .filter(nid=1)
 7      .extra(select{"standard_time":"strftime(‘%%Y%%m%%d‘,create_time)"}).values("standard_time","nid","title")
 8 print(article_obj)
 9     # <QuerySet [{‘title‘: ‘MongoDb 入门教程‘, ‘standard_time‘: ‘2017-09-03‘, ‘nid‘: 1}]>
10 
11 
12 参数之where / tables:简单条件查询
13 您可以使用tables手动将表添加到SQL FROM子句,where和tables都接受字符串列表
14 queryResult=models.Article.objects.extra(where=[nid in (1,3) OR title like "py%" ,nid>2])
15 ## table连接其它表
16 # SELECT * FROM myapp_book, myapp_person WHERE last = author_last
17 Book.objects.all().extra(table=[myapp_person], where=[last = author_last]) # 加from后面

 

以上是关于model进阶(queryset,中介模型,查询优化,extra)的主要内容,如果未能解决你的问题,请参考以下文章

Django学习之model进阶

Django-model进阶

python之路_day80_models模型进阶

04 Django模型层: Django-model进阶

模型层进阶相关

Django 模型系统(model)&ORM--进阶