Reputation: 638
I have a model, which looks something like this:
class Agent(models.Model):
class Meta:
ordering = ['first_name', 'last_name', ]
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
... some other fields ...
class Point(models.Model):
agent = models.ForeignKey(Agent)
... some other fields ...
When I select some points I want them to be ordered by agent names, like this:
points = Point.objects.filter(...smth...).order_by(-agent)
So the resulting queryset is ordered by agent names, from Z to A
or
points = Point.objects.filter(...smth...).order_by(agent)
or even without ordering
The question is:
How to get a queryset or a list of unique agent objects from points
queryset, preserving the ordering?
Preferrably, without any more order_by()
statements, because the view may or may not be explicitly aware of ordering type
Something like set(points.values_list('agent', flat=True))
, but with objects instead of pk-s?
Upvotes: 1
Views: 566
Reputation: 73450
You can use your own idea and nest it like so (where points
is any QuerySet
of Point
):
Agent.objects.filter(id__in=points.values_list('agent', flat=True))
Django ORM will translate this into a single db query. This should have Agent
's default order. In order to preserve the agent order in points, you could do:
[p.agent for p in points.distinct('agent')]
This workaround, obviously, is not a queryset and distinct
with field arguments is only supported in Postgres.
Upvotes: 1
Reputation: 8960
This should work.
Agent.objects.filter(id__in=Point.objects.values_list('agent_id', flat=True)).order_by('-first_name')
Update:
Point.objects.filter(agent_id__in=Agent.objects.values_list('id', flat=True)).distinct('agent').order_by('-agent__first_name')
Upvotes: 0
Reputation: 368894
Use Agent objects manager, and QuerySet.distinct
to get unique agents:
Agent.objects.filter(point__condition=...).distinct().order_by('-pk')
NOTE: condition=...
should be adjusted to point__condition=...
.
Upvotes: 0