问题
I have data in the following form:
collection_name | type | manufacturer | description | image_url
---------------------------------------------------------------------------
beach | bed | company a | nice bed | 1.jpg
beach | king bed | company a | nice bed | 1.jpg
beach | nightstand | company a | nice ns | 1.jpg
grass | chest | company a | nice chest | 2.jpg
apple | chest | company a | nice chest | 3.jpg
fiver | chest | company b | good chest | 4.jpg
What I need to do, is select all images and only return each image once (distinct), but then return non-distinct row for each image.
My goal is to ensure I display each image only once in my template, but show all records associated with each image.
In the example above, 1.jpg is one image that would show both beds and the nightstand in one image. I would like to show such an image and list associated products with it.
I have seen similar questions, although asking at the SQL/db level and not asking for a pure django solution.
The query I have been using in my view has been something like:
products = product.objects.filter(collection_name=name)
and then iterating over products, retrieving image_url like so:
{% for instance in products %}
{{ instance.image_url }}
{{ endfor }}
I've tried various attempts to limit repeating images in my template, but none have really worked, and attempts to do so in my view have not been successful.
What is the correct way to approach this?
Edit: A relevant excerpt from my models to match the sample data above:
class Product(models.Model):
collection_name = models.TextField(null='true',blank='true')
type = models.TextField(null='true',blank='true')
manufacturer = models.TextField(null='true',blank='true')
description = models.TextField(null='true',blank='true')
image_url = models.TextField(null='true',blank='true')
Edit: My idea of views and logic to attempt to solve this, after reading the docs and looking at other questions (no answers):
Pass the product_id of any product in a collection to the view. Then obtain the collection_name field of a record based on the id field:
collectionname = product.objects.filter(id=id).values('collection_name').distinct()
Then, when we have the collection_name field, return all products for a given collection_name:
products = product.objects.filter(collection_name__in=collectionname)
Then, finally, return a list of image_url results for a given collection name, removing duplicates:
images = product.objects.filter(collection_name__in=collectionname).values('image_url').distinct()
I think this should work, in theory...
Edit:
Currently attempting the following based on Juancarlos' answer below:
products = product.objects.filter(collection_name=name)
collectionname = product.objects.filter(id=id).values('collection_name').distinct()
images = product.objects.filter(collection_name__in=collectionname).values("image_url").distinct()
results = []
for img in images:
pbis = product.objects.filter(collection_name__in=collectionname, image_url=img['image_url'])
obj = {"image": img['image_url'], "items":[{"type":pbi.type} for pbi in pbis]}
results.append(obj)
回答1:
mabe this logic can help you, i am not sure but you can do something like this:
images = product.objects.filter(collection_name=name).values("image_url").distinct()
results = []
for img in images:
pbis = product.objects.filter(collection_name=name, image_url=img['image_url'])###this get all record tha contains this image
obj = {"image": img['image_url'], "items":[{"attr":pbi.attr, ...} for pbi in pbis]}
results.append(obj)
###this iterate all record by images and you can store items attribute from all recors that contains that image
回答2:
You need tell to django what field you want distinct, you can use values
to do that:
in your case your answer can seen like this:
products = product.objects.filter(collection_name=name).values("image_url").distinct()
来源:https://stackoverflow.com/questions/55067576/django-return-all-associated-rows-for-distinct-results-set-with-postgres-backe