sort django queryset by latest instance of a subset of related model

南笙酒味 提交于 2019-12-02 01:16:31

Ok, I think you can achieve this with the extra method, but not, as far as I can tell, with pure database-agnostic orm. This means you'll have to ensure your sql works for the db backend you're using, and to be wary of django aliasing the table names, but it will also mean you can do it all with one query.

Something along these lines should work:

latest_event_subquery = 'select max(event_datetime) ' \
                        'from appname_order_event ' \
                        'where appname_order_event.category="scheduling" and ' \
                              'appname_order_event.event_id=appname_order.id'
queryset = Order.objects.extra(select={'latest_event_date': latest_event_subquery}).order_by('latest_event_date')

Does that make sense?

Greg's answer is great, and I used it for awhile. However, I wanted to access other fields of latest_event. So, I ended up storing the latest_event as a field of Order:

# The latest event
latest_event = db.ForeignKey('whateverapp.Event', editable=False, null=True)

Then I set up a signal to recalculate the latest event upon save:

@receiver(post_save, sender=Event)
def visit_calculate_latest(sender, instance, **kwargs):
    """Recalculate latest event"""
    instance.parent.latest_event = instance.parent.get_latest_event()

where get_latest_event() did the query:

def get_latest_event(self):
    """Return most recent event or None."""
    try:
        return Event.objects.filter(
            parent=self.id).order_by('-event_date', '-id')[0]
    except IndexError:
        return None

Now I can filter by latest_event__whatever:

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