django orm跨关系查询(跨表,多层查询)

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

猜你喜欢

转载自blog.csdn.net/pushiqiang/article/details/81127442