获取 Django 中所有唯一的 prefetch_related 对象

Ant*_*min 4 python django prefetch django-queryset

在models.py中:

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

如果我有一个 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()]
Run Code Online (Sandbox Code Playgroud)

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

PS当然我们可以在«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()]
Run Code Online (Sandbox Code Playgroud)

返回:

[<Product: Vestibulum ante ipsum primis in>, <Product: Vivamus quis turpis>, <Product: Pellentesque habitant>, <Product: Vivamus quis turpis>]
Run Code Online (Sandbox Code Playgroud)

其中<Product: Vivamus quis turpis>反复

PS有人知道吗?

Mar*_*way 5

您可以使用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()]))
Run Code Online (Sandbox Code Playgroud)