【问题标题】:Filter parent objects which have no children object using prefetch_related使用 prefetch_related 过滤没有子对象的父对象
【发布时间】:2021-07-12 06:06:40
【问题描述】:

我有以下三个模型,Seller 作为祖父母,Genre 作为父母,Book 作为孩子:

class Seller(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class Genre(models.Model):
    seller= models.ForeignKey(Seller, related_name="genre",  on_delete=models.CASCADE)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name


class Book(models.Model):
    genre= models.ForeignKey(Genre, related_name="book",  on_delete=models.CASCADE)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

如果我使用prefetch_related() 在一个数据库查询中获取Seller 对象及其GenreBook,如下所示:

sellers = Seller.objects.prefetch_related('genre__book').filter()

但是,我想过滤掉与 Book 对象无关的 Seller 对象。在这种情况下,filter() 的语法是什么?

【问题讨论】:

    标签: django


    【解决方案1】:

    要过滤没有书籍的类型,您需要以下条件:

    genres = Genre.objects.exclude(pk__in=[x.genre.pk for x in Book.objects.all()]
    

    要将其与prefetch_related 结合使用,我认为您需要将Prefetch 对象与给定的查询集一起使用

    from django.db.models import Prefetch
    
    sellers = Seller.objects.prefetch_related(
        Prefetch('genre_set', 
                 queryset=Genre.objects.exclude(pk__in=[x.genre.pk for x in Book.objects.all()])
        )
    

    【讨论】:

    • 感谢您的代码。这个genres = Genre.objects.exclude(pk__in=[x.genre.pk for x in Book.objects.all()] 按预期工作(虽然它与我的过滤意图相反,所以我将exclude 更改为filter。但是当与上面的Prefetchprefetch_related 一起使用时,查询总是返回整个列表Seller 数据库中的对象。也就是说,它没有过滤掉那些为空的Book。Mayeb 关于Prefetch?我正在进一步检查。
    • 我也可以建议您尝试一下:sellers = Seller.objects.select_related('genre__book').filter(pk__in=[x.genre.pk for x in Book.objects.all()]) 可能这就是您要找的东西
    猜你喜欢
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 2015-06-21
    相关资源
    最近更新 更多