使用Django的pre_fetch_related函数

时间:2016-12-22 08:06:49

标签: django django-queryset

鉴于以下情况:

在图书馆中,一本书只能放在一个袖子里。在整个过程中,这本书可以从袖子到袖子。

模特

class Sleeve(models.Model):
  sleeve_name = models.CharField(max_length=60)
  sleeve_number = models.DecimalField()

class Book(models.Model):
  book_title = models.CharField(max_length=120)
  sits_in_sleeve = models.ForeignKey(Sleeve, null=False)

现在我想创建一个Django Queryset来查询所有具有1到10之间数字的Sleeves,并查询属于它的所有书籍标题。如何使用prefetch_related

这样做

换句话说,我可以这样做:

sleeves = Sleeve.objects.filter(sleeve_number__lte=10,sleeve_number__gte=1)
for s in sleeves:
  b = Book.objects.get(sits_in_sleeve=s)
  s.book = b

但有更优雅的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以这样做:

b = Book.objects.filter(sits_in_sleeve__sleeve_number__lte=10,sits_in_sleeve__sleeve_number__gte=1)

因为Book模型有一个名为 sits_in_sleeve 的字段,它与Sleeve模型有外键关系。

因此,您可以通过添加双下划线(__)来获取Sleeve模型字段的任何操作,以获取相关Sleeve模型的字段。

<强>更新

正如Sayse建议的那样,您也可以使用范围功能而不是单独使用__gte和__lte。 像这样:

b = Book.objects.filter(sits_in_sleeve__sleeve_number__range=(1,10))

答案 1 :(得分:1)

您可以使用 prefetch_related

执行此操作
sleeves = Sleeve.objects.filter(sleeve_number__lte=10,sleeve_number__gte=1).prefetch_related('book_set')

然后,您可以获取每个袖子的书籍而无需进行其他查询:

for sleeve in sleeves:
    books = sleeve.book_set.all()