1. 程式人生 > >model進階(queryset,中介模型,查詢優化,extra)

model進階(queryset,中介模型,查詢優化,extra)

註意 簡單 foreign utils 自動創建 中介 ... ant reason

中介模型:

針對多對多關系,雖然可以自動創建關聯表,但是需求是想要加入一些字段信息呢,這就需要自己手動建關聯表了

對於這些情況,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可以指定一個或多個 參數,例如 select, where 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)