django orm跨關係查詢(跨表,多層查詢)
阿新 • • 發佈:2019-01-07
django orm跨關係查詢(ManyToManyField,ForeignKey多層查詢)
Django提供了一種強大而直觀的方式來“跟蹤”查詢中的關係,在後臺自動用SQL JOIN處理。 要跨越關係,只需使用跨模型的相關欄位的欄位名稱,用雙下劃線分隔,直到到達所需的欄位。
這個例子檢索所有Entry物件的 Blog,其name 為:’Beatles Blog’
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255 )
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self): # __unicode__ on Python 2
return self.headline
>>> Entry.objects.filter(blog__name='Beatles Blog')
這種跨越可以像你想的那樣深,可以刮越多層查詢(不止兩層)。
例如:
from django.db import models
class User(models.Model):
phone = models.CharField(max_length=50, unique=True)
class Store(models.Model):
name = models.CharField(_('Name'), max_length=50)
class Group(BaseModel):
name = models.CharField(_('Name'), max_length=50)
members = models.ManyToManyField(
User,
verbose_name='Members',
related_name='groups'
)
store= models.ForeignKey(
'Store',
verbose_name=_('Belong store'),
related_name="groups",
related_query_name="group",
)
查詢所屬的組名為’owner’ 且使用者電話號碼為 search_term的商店:
queryset = Store.objects.filter(
group__name='owner',
group__members__phone__contains=search_term
)
表間關係: A(User) <–AB(中間表)–> B(Group) –> C(Store)
queryset 的查詢最終經過3層查詢,跨越了4張表
它也可以反向查詢。要引用“反向”關係,只需使用模型的小寫名稱即可。
這個例子檢索所有Blog具有至少一個物件Entry ,其headline包含’Lennon’:
>>> Blog.objects.filter(entry__headline__contains='Lennon')