首页 > 解决方案 > Django 过滤与 QuerySet 中的模型相关的模型

问题描述

我的应用程序中BookReview模型,Review外键字段指向Book.

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from datetime import datetime


 class Book(models.Model):
    title = models.CharField(max_length=300, null=False, blank=False)
    category = models.CharField(max_length=40, blank=True)

class Review(models.Model):
    reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False)
    date_last_modified = models.DateTimeField(null=True)
    is_closed = models.BooleanField(default=False)

现在,通过应用一些过滤器,我有一个(例如来自某些的书QuerySet)。Bookscategory

books_qs = Book.objects.filter(category='World War II') 

有了这个QuerySet,我想为每个给定日期找到最新Review的。最简单的解决方案当然是:is_closed=TrueBook

desired_date = datetime(2018, 2, 12)

reviews = []
for book in books_qs:
    try:
        latest = book.review_set.filter(date_last_modified__lt=desired_date, is_closed=True).latest('date_last_modified')
    except Book.DoesNotExist:  # latest() throws this exception if Book has no reviews
        continue
    else:
        reviews.append(latest)

有没有办法改进这一点以Reviews在一个查询中获取所有内容,而不是在每个循环中多次执行Book

标签: pythondjangopython-3.xdjango-models

解决方案


表达您的问题的另一种方式是,您想过滤所有书籍分类为“二战”、之前修改过的评论desired_date,并按is_closed书籍分组并获取最新评论。

因此,我们将按照这些标准过滤我们的评论。然后我们将查询集排序bookdate_last_modified这样当我们在 上取不同的值时book,它们将按我们想要在每个组中取“第一个”的字段进行排序。

Review.objects.filter(
    date_last_modified__lt=desired_date, is_closed=True,
    book__category='World War II',
).order_by("book", "-date_last_modified").distinct("book")

推荐阅读