Retrieving distinct records based on a column on Django

折月煮酒 提交于 2020-01-01 09:17:13

问题


I need to retrieve a list of records for the following table with distinct values in regards to name:

Class C:

name                value
A ------------------ 10
A ------------------ 20
A ------------------ 20
B ------------------ 50
C ------------------ 20
D ------------------ 10
B ------------------ 10
A ------------------ 30

I need to get rid of all the duplicate values for name and only show the following:

name                value
A ------------------ 30
B ------------------ 10
C ------------------ 20
D ------------------ 10

As you can see, it almost looks like a python set. I can probably generate the set using Python, but I'm wondering if Django's ORM has this feature.

I tried using distinct, but it doesn't accept any argument to specify which column has to have distinct values. Any idea how to get this query working?


回答1:


.distinct() is the tool, but here's the syntax I had to use :

Model.objects.values_list('name', flat=True).distinct()

This way you only get a list [A,B,C,D] of values, not the objects themseleves.




回答2:


Problem with sqlite distinct is it distincts on all returned values. To distinct on one column name, for example: 'url' to get all unique urls from a table, but also get the rest of the data, use a subquery.

The subquery gets the IDs of the url's and then uses that to do another query on those ideas. This is not as quick as a regular distinct of course.

link_ids = (
    Resources
    .values('url')
    .distinct()
    .annotate(
        occurrences=Count('url'),  # make unique 'urls' only occur once.
        pk=Min('pk')  # return pk of first occurrence
    )
)
broken_links_qs = (
    Resources.filter(id__in=Subquery(link_ids.values('pk')))
)

(At the time the previous answers where given, django did not have Subquery functionality yet.)




回答3:


You can also use raw like:

queryraw = C.objects.raw('SELECT name, value FROM prj_c GROUP BY name')

or add an ORDER BY to have the higher value for any group:

queryraw = C.objects.raw('SELECT name, value FROM prj_c GROUP BY name ORDER BY value')

In any case you can have list() of objects.

Usefull documentation here: https://docs.djangoproject.com/en/2.0/topics/db/sql/




回答4:


This isn't super elegant but it gets the job done in about one line:

# Fetch all rows to limit num of queries
all_rows = MyModel.objects.all()

# Query against the full list to return a list of objects
item_list = [all_rows.filter(myfield=item['myfield']).last() for item in MyModel.objects.values('myfield').distinct()]

This retrieves the full model instance for each of the values you're doing the DISTINCT on. Some use cases might need different filtering.

Then just use the name and value properties in each item on item_list to get your distinct data.




回答5:


Using the following syntax should solve your problem. values('name', 'value').distinct()



来源:https://stackoverflow.com/questions/4723220/retrieving-distinct-records-based-on-a-column-on-django

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