简体   繁体   English

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

[英]get all unique prefetch_related objects in Django

in models.py: 在models.py中:

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

if i have a queryset of Product how can i get all unique recommended objects? 如果我有一个产品的查询集,我如何获得所有独特的推荐对象?
example: product «A» has 3 recommended products: «B», «C» and «D», product «B» has 2 recommended products: «C» and «E», in queryset «products» we have «A» and «B» products, in this example: 例如:产品«A»有3个推荐产品:«B»,«C»和«D»,产品«B»有2个推荐产品:«C»和«E»,在查询集«产品»我们有«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()]

we will get list of [«B», «C», «D», «C», «E»], but how to get only [«B», «C», «D», «E»]? 我们将获得[«B»,«C»,«D»,«C»,«E»]列表,但如何只获得[«B»,«C»,«D»,«E»]?

PS of course we can filter objects in «for» cycle, but maybe there's more effective and fair way? PS当然我们可以在«for»循环中过滤对象,但也许有更有效和公平的方式? ... ...

Update #1 (answer to Mark Galloway): 更新#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()]

returns: 收益:

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

where <Product: Vivamus quis turpis> repeated 其中<Product: Vivamus quis turpis>重复

PS does anybody knows? PS有人知道吗?

You can define a more specific query for prefetch_releated by using a Prefetch object. 您可以使用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()]))

Assuming your model is as follows (from your description and output, I am assuming you must have symmetrical=False ): 假设您的模型如下(根据您的描述和输出,我假设您必须具有symmetrical=False ):

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

Then I think the following does what you are after: 然后我认为以下是你所追求的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM