dan
dan

Reputation: 552

Django ORM, aggregation?

Not sure how to phrase question, but here goes.

Say i have a table of events, and each event links to a object using a generic foreign key.

I dont want to show two events that link to the same foreign object, only the most recent event out of those which link to the same object.

Can anyone give any hints?

Upvotes: 0

Views: 231

Answers (2)

sheats
sheats

Reputation: 34662

I think it may be very hard to do what you are asking. Since you are looking for a list of events and using generic relations, your only bet is probably to add some SQL via the .extra() filter. I'm not sure I would even know what SQL you would need to run for this since it would probably need GROUP BY and HAVING clauses.

As an alternative though, consider adding a BooleanField to your event object called latest. Then in the save method of your event, write some code like this:

def save(self, *args, **kwargs):
    similar_events = Event.objects.filter(content_type=self.content_type,
                                          object_id=self.object_id)
    later_events = similar_events.filter(date__gt=self.date)
    if later_events:
        self.latest = False
    else:
        self.latest = True
        similar_events.filter(date__lte=self.date).update(latest=False)

    super(Event, self).save(*args, **kwargs)

Then to get your list of events simply do this:

Event.objects.filter(latest=True)

Upvotes: 2

sykloid
sykloid

Reputation: 101176

When you use foreign keys to point to a model, the model which is pointed to gets a descriptor referring to all the models that point to it. By default this is modelname_set, or event_set in this case, unless you've changed it.

You can use this descriptor to get the most recent event for the object. Since the descriptor returns a query set, you can order it by the date field, and take the first one.

  latest_event_for_obj = obj.entry_set.order_by('-your_date_field')[0]

Upvotes: 0

Related Questions