complex annotate on django query set

只谈情不闲聊 提交于 2019-12-11 02:37:46

问题


I have an issue where I can't quite get all the information I need from a complex .annotate() call in my django view. Here's my model:

RECORD_STATUS = (
    (0, "Hidden"),
    (1, "Unhidden"),
    (2, "Deleted"),
)
class Activity(models.Model):
    event_date = models.DateTimeField()
    duration = models.IntegerField(default=0)
    username = models.CharField(max_length=200)
    record_id = models.CharField(max_length=100)
    record_status = models.IntegerField(choices=RECORD_STATUS)
    record_quality = models.FloatField(default=0)

I'd like to pass the following values based on a distinct record_id to my view template:

  • average quality
  • count
  • latest event_date
  • total duration

and...

...latest status (status of Activity with the latest event_date for a particular record_id)

I've been able to get most of these as intended, with the following queryset codechunk but I am unable to grab the latest status for a particular record_id. I'm inclined to believe an .extra() call might be the way to go, but I can't seem to construct it properly.

record_id_details = Activity.objects.values(
    'record_id',
    ).annotate(
    ave_quality=Avg('record_quality'),
    count=Count('id'),
    latest_event_date=Max('event_date'),
    total_duration=Sum('duration'),
    # Here's where I'm going wrong
    # I need the record_statuses from the most recent Activities of each record_id
    latest_status=,# dont know... record_status WHERE Max(event_date) ???
).order_by(sort)

Any advice as to an annotate argument that would give me what I need, or perhaps some help constructing the extra command would be appreciated. Thanks!


回答1:


There's no builtin way to express this query with a Django queryset. Performing it in two queries is probably the easiest way to do it purely with the ORM. If you don't mind some raw SQL, and you're using a database that supports it, like PostgreSQL, the tool you'll want is called a Window Function, you can find good detail here: http://www.postgresguide.com/tips/window.html




回答2:


I would just execute a second query so that I could keep all of that separated. Something like:

latest = Activity.objects.filter(record_id="whatever_the_record_id_you_want").order_by("-event_date)
most_recent = latest[0]
what_you_asked_for = most_recent.record_status


来源:https://stackoverflow.com/questions/15691681/complex-annotate-on-django-query-set

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