Django - return all associated rows for distinct results set with postgres backend

China☆狼群 提交于 2019-12-24 18:51:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!