Django框架多表查詢實(shí)例分析
本文實(shí)例講述了Django框架多表查詢。分享給大家供大家參考,具體如下:
多表查詢是模型層的重要功能之一, Django提供了一套基于關(guān)聯(lián)字段獨(dú)特的解決方案.
ForeignKey
來自Django官方文檔的模型示例:
from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() class Entry(models.Model): blog = models.ForeignKey(Blog) authors = models.ManyToManyField(Author) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField()
class ForeignKey
ForeignKey字段接受一個Model類作為參數(shù), 類型與被參照的字段完全相同:
blog = models.ForeignKey(Blog)
ForeignKey.to_field
關(guān)聯(lián)到的關(guān)聯(lián)對象的字段名稱。默認(rèn)地,Django 使用關(guān)聯(lián)對象的主鍵。
blog = models.ForeignKey(Blog, to_field=Blog.name)
ForeignKey.db_constraint
Django Model的ForeignKey字段的主要功能是維護(hù)一個一對多的關(guān)系, 以進(jìn)行關(guān)聯(lián)查詢.
只有在db_constraint=True
時Django model才會在數(shù)據(jù)庫上建立外鍵約束, 在該值為False時不建立約束.
默認(rèn)db_constraint=True
.
ForeignKey.related_name
這個名稱用于讓關(guān)聯(lián)的對象反查到源對象.
如果你不想讓Django 創(chuàng)建一個反向關(guān)聯(lián),請?jiān)O(shè)置related_name 為 '+' 或者以'+' 結(jié)尾.
ForeignKey.related_query_name
以ForeignKey.related_name
作為默認(rèn)值, 兩者功能的具體說明請參見相關(guān)文檔
使用ForeignKey查詢
前向查詢
若關(guān)系模型A包含與模型B關(guān)聯(lián)的關(guān)聯(lián)字段, 模型A的實(shí)例可以通過關(guān)聯(lián)字段訪問與其關(guān)聯(lián)的模型B的實(shí)例:
>>> e = Entry.objects.get(id=2) >>> e.blog # Returns the related Blog object.
修改e.blog
并調(diào)用save方法存入數(shù)據(jù)庫
>>> e.blog = some_blog >>> e.save()
如果ForeignKey 字段有null=True
設(shè)置(即它允許NULL值),可以分配None來刪除對應(yīng)的關(guān)聯(lián)性
>>> e = Entry.objects.get(id=2) >>> e.blog = None >>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
Django提供了一種使用雙下劃線__
的查詢語法:
>>> Entry.objects.filter(blog__name='Beatles Blog')
反向查詢
被索引的關(guān)系模型可以訪問所有參照它的模型的實(shí)例,如Entry.blog作為Blog的外鍵,默認(rèn)情況下Blog.entry_set
是包含所有參照Blog的Entry示例的查詢集,可以使用查詢集API取出相應(yīng)的實(shí)例。
>>>b = Blog.objects.get(id=1) >>>b.entry_set.all()
Entry.blog的related_name和related_query_name可以設(shè)置該查詢集的名字。
ManyToManyField
來自Django官網(wǎng)的示例:
from django.db import models class Person(models.Model): name = models.CharField(max_length=50) class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership', through_fields=('group', 'person')) class Membership(models.Model): group = models.ForeignKey(Group) person = models.ForeignKey(Person) inviter = models.ForeignKey(Person, related_name="membership_invites") invite_reason = models.CharField(max_length=64)
class ManyToManyField
ManyToManyField.through
Django 會自動創(chuàng)建一個表來管理多對多關(guān)系, 若要手動指定關(guān)聯(lián)表則需要使用through關(guān)鍵字參數(shù).
ManyToManyField.through_fields
上文示例中Membership 有兩個外鍵指向Person (person 和inviter),這使得關(guān)聯(lián)關(guān)系含混不清并讓Django 不知道使用哪一個。
在這種情況下,必須使用through_fields 明確指定Django 應(yīng)該使用哪些外鍵
through_fields 接收一個二元組('field1', 'field2'),其中field1 為指向定義ManyToManyField 字段的模型的外鍵名稱(本例中為group),field2 為指向目標(biāo)模型的外鍵的名稱(本例中為person).
ManyToManyField.db_table
默認(rèn)情況下,關(guān)聯(lián)表的名稱使用多對多字段的名稱和包含這張表的模型的名稱以及Hash值生成,如:memberShip_person_3c1f5
若要想要手動指定表的名稱,可以使用db_table
關(guān)鍵字參數(shù)指定.
others
下列API和ForeignKey中的同名API相同.
- ManyToManyField.db_constraint
- ManyToManyField.related_name
- ManyToManyField.related_query_name
使用ManyToManyField查詢
多對多關(guān)系和ForeignKey具有相似的API.
>>>e = Group.objects.get(id=3) >>>e.members.all() # Returns all members objects for this Group.
反向查詢:
>>>a = Person.objects.get(id=1) >>>a.group_set.all()
同樣related_name可以設(shè)置反向查詢集的名稱。
添加刪除關(guān)聯(lián)
因?yàn)镸anyToManyField自動維護(hù)關(guān)聯(lián)表,程序員不便于直接訪問.ManyToManyField提供了API用于添加和刪除關(guān)聯(lián)(即through表中的記錄).
使用一個自動維護(hù)through表的模型作為示例:
class User(models.Model): user_id = models.IntegerField(primary_key=True) class Flight(models.Model): flight_id = models.IntegerField(primary_key=True) reserve = models.ManyToManyField(User, related_name='flight_reserve')
首先獲得要進(jìn)行關(guān)聯(lián)的Flight和User實(shí)例:
flights = Flight.objects.filter(flight_id=flight_id) if flights.count() != 0: flight = flights[0] users = User.objects.filter(id=user_id) if users.count() != 0: user = users[0]
通過擁有關(guān)聯(lián)字段的Flight實(shí)例進(jìn)行添加關(guān)聯(lián)操作:
flight.reserve.add(user) flight.save()
刪除操作與這類似:
flight.reserve.remove(user) flight.save()
希望本文所述對大家基于Django框架的Python程序設(shè)計有所幫助。
相關(guān)文章
詳解tensorflow訓(xùn)練自己的數(shù)據(jù)集實(shí)現(xiàn)CNN圖像分類
本篇文章了tensorflow訓(xùn)練自己的數(shù)據(jù)集實(shí)現(xiàn)CNN圖像分類,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02對django的User模型和四種擴(kuò)展/重寫方法小結(jié)
今天小編就為大家分享一篇對django的User模型和四種擴(kuò)展/重寫方法小結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python利用memory_profiler實(shí)現(xiàn)內(nèi)存分析
memory_profiler是第三方模塊,用于監(jiān)視進(jìn)程的內(nèi)存消耗以及python程序內(nèi)存消耗的逐行分析。本文將利用memory_profiler實(shí)現(xiàn)內(nèi)存分析,需要的可以參考一下2022-10-10Python 實(shí)現(xiàn)網(wǎng)頁自動截圖的示例講解
今天小編就為大家分享一篇Python 實(shí)現(xiàn)網(wǎng)頁自動截圖的示例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05安裝Python和pygame及相應(yīng)的環(huán)境變量配置(圖文教程)
下面小編就為大家?guī)硪黄惭bPython和pygame及相應(yīng)的環(huán)境變量配置(圖文教程)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06python 列表推導(dǎo)和生成器表達(dá)式的使用
這篇文章主要介紹了python 列表推導(dǎo)和生成器表達(dá)式的使用方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-02-02Python迭代器協(xié)議及for循環(huán)工作機(jī)制詳解
這篇文章主要介紹了Python迭代器協(xié)議及for循環(huán)工作機(jī)制詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07使用Python-OpenCV向圖片添加噪聲的實(shí)現(xiàn)(高斯噪聲、椒鹽噪聲)
這篇文章主要介紹了使用Python-OpenCV向圖片添加噪聲的實(shí)現(xiàn)(高斯噪聲、椒鹽噪聲) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05Python實(shí)現(xiàn)數(shù)據(jù)透視表詳解
今天小編就為大家分享一篇用Python實(shí)現(xiàn)數(shù)據(jù)的透視表的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-10-10