1. 程式人生 > >django orm跨關係查詢(跨表,多層查詢)

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