in 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:
# 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»]?
PS of course we can filter objects in «for» cycle, but maybe there's more effective and fair way? ...
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
PS does anybody knows?
You can define a more specific query for prefetch_releated by using a Prefetch object.
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
):
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>]>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.