简体   繁体   中英

Django retrieve rows for the distinct column values

I want to query Model rows in Django,

class Language(models.Model):
    language_id = models.CharField(max_length=100, default="")
    code = models.CharField(max_length=100, default="")
    name = models.CharField(max_length=500, default="")

In this table, the language_id is not unique, for example, below is the sample data

+-------------+------+---------+
| language_id | code | name    |
+-------------+------+---------+
|       12345 | en   | english |
|       12345 | te   | telugu  |
|       54321 | en   | english |
|       54321 | te   | telugu  |
+-------------+------+---------+

I want to filter the rows(all columns) which should have distinct language_id s.

What currently I am doing.

language_list = Language.objects.all()

list = []
idlist = []

for language in language_list:
    if language.language_id not in idlist:
        il = language
        list.append(il)
        idlist.append(language.language_id)

Then list will have all the distinct rows(model objects).

Is there any better way to do this. I don't want to rotate through all the language models.

It's unclear what you are trying to do. What your script does is take the first occurrence of a given ID arbitrarily. If that's what you want, it will depend on what database your model is based. PostgreSQL allows the use of distinct on a field: https://docs.djangoproject.com/en/2.1/ref/models/querysets/#distinct

On MySQL what you could do is get all the unique instances of your id and get an instance of your model matching once per ID:

language_ids = Language.objects.values_list('language_id', flat=True).distinct()
result = []
for language_id in language_ids:
    result.append(Language.objects.filter(language_id=language_id).first())

It's not necessarily much better than your solution simply because arbitrary picking isn't an expected use case for the ORM.

If on the other hand you meant to only get language_ids that appear once and only once:

Language.objects.values('language_id').annotate(cnt=Count('id')).filter(cnt=1)

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.

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