Django-queryset gets one object per field = foo

I have a basic FK for a user, call it owner

class Baz(models.Model):

    owner = models.ForeignKeyField(User)


    ....
    ....

      

Now, with Baz's request, is there something I can tie that would only give me one Baz per owner?

+2


source to share


4 answers


This is probably not the best solution (I would like to keep it in memory and in queries), but:

>>> d={}
>>> [d.setdefault(str(a.owner),a) for a in qs ]
>>> d.values()

      



returns a list of objects, the last one for each owner. I have real reservations about the scalability of this solution.

+1


source


I believe the question is how to run the equivalent of this:

SELECT * FROM myapp_baz GROUP BY owner_id;

      

Which will return one row for each unique owner_name.



It looks like it does the trick:

qs = Baz.objects.all()
qs.query.group_by = ['owner_id']

# Seems to do the trick
print [item for item in qs]

      

+3


source


The function you are really looking for is GROUP BY. However, Django generally does not support making requests that do not directly output model instances. In this situation, you have two approaches:

Baz.objects.values('owner').distinct()

      

This will give you each individual owner, but not the Baz object itself.

Baz.objects.filter(pk__in=Baz.objects.values('owner').distinct())

      

The above will execute a subquery (at least in MySQL) and should give the expected results, but not the most efficient way to retrieve it.

Finally, since the aggregates have been added, you may be able to write a custom aggregate class that acts as a sort of "Distinct" and just "GROUP BY".

+2


source


EDIT : It's more likely to work:

CheckIn.objects.extra(where=['checkins_checkin.id = (SELECT MAX(checkins_checkin.id) FROM checkins_checkin temp, auth_user WHERE auth_user.id = temp.id AND temp.user_id = checkins_checkin.user_id)',]).count() 

      

0


source







All Articles