【问题标题】:get all unique prefetch_related objects in Django获取 Django 中所有唯一的 prefetch_related 对象
【发布时间】:2015-07-16 10:04:04
【问题描述】:

在models.py中:

from django.db import models
...
class Product(models.Model):
   ...
   recommended = models.ManyToManyField('self', blank=True)
   ...

如果我有一个 Product 查询集,我如何获得所有唯一的推荐对象?
例如:产品«A»有3个推荐产品:«B»、«C»和«D»,产品«B»有2个推荐产品:«C»和«E»,在查询集«products»中我们有«A»和«B»产品,在本例中:

# get_products() returns QuerySet of «A» and «B» products
products = get_products().prefetch_related('recommended')
recommended = [item for p in products for item in p.recommended.all()]

我们会得到 [«B», «C», «D», «C», «E»] 的列表,但是如何只得到 [«B», «C», «D», «E »]?

附:当然我们可以在 «for» 循环中过滤对象,但也许有更有效和公平的方法? ...

更新 #1(对 Mark Galloway 的回答):

products = self.request.basket.get_products().prefetch_related(
        Prefetch('recommended', queryset=models.Product.objects.distinct()))
recommended_list = [item for p in products for item in p.recommended.all()]

返回:

[<Product: Vestibulum ante ipsum primis in>, <Product: Vivamus quis turpis>, <Product: Pellentesque habitant>, <Product: Vivamus quis turpis>]

&lt;Product: Vivamus quis turpis&gt; 重复的地方

附:有人知道吗?

【问题讨论】:

    标签: python django django-queryset prefetch


    【解决方案1】:

    您可以使用Prefetch 对象为 prefetch_releated 定义更具体的查询。

    prefetch = Prefetch('recommended', queryset=Product.objects.distinct()))
    products = get_products().prefetch_related(prefetch)
    recommended_list = list(set([item for p in products for item in p.recommended.all()]))
    

    【讨论】:

    • @AntonVahmin 我认为关键是这个人建议将结果转换为一个集合以消除重复,这实际上并不能解决查询返回重复的问题,但确实会给你结果你想要的。
    【解决方案2】:

    假设你的模型如下(根据你的描述和输出,我假设你必须有symmetrical=False):

    class Product(models.Model):
        recommended = models.ManyToManyField('self', blank=True, symmetrical=False, related_name='recommended_by')
    

    那么我认为以下是你所追求的:

    Product.objects.filter(recommended_by__in=get_products()).distinct()
    >>> <QuerySet [<Product: B>, <Product: C>, <Product: D>, <Product: E>]>
    

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多