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')