user764357
user764357

Reputation:

Default ordering of model by date with nulls coming first

In Django, you can define the default ordering of models with the ordering meta option.

If your model is:

class Event(models.Model):
    title = models.TextField()
    start_date = models.DateField()
    end_date = models.DateField(null=True, blank=True)

We can fix the ordering of the model, like so:

    class Meta:
        ordering = ['-end_date','-start_date']

Which will put events with the most recent end dates first, and in the case of a tie sort by events with the most recent start date.

However, some events may still be happening, hence a nullable end_date. These are the mostest recent events in the system, yet these are being ordered after everything else.

In Django, how can I specify an ordering on a date field such that it is descending, but with null fields coming first?

If that's not possible, how can I write the query for the field to get the same effect?

Upvotes: 2

Views: 1726

Answers (2)

dum4ll3
dum4ll3

Reputation: 1467

I know I'm late for the party but I've just had this exactly same question and the solution is to use query expressions as described in the docs like so:

ordering = (F("end_date").desc(nulls_first=True))

Upvotes: 3

NeoWang
NeoWang

Reputation: 18533

I looked around Django's DB code, it looks Django doesn't provide any hook to customize the processing of 'ordering' meta option, all it does is to generate the ORDER BY part of SQL with ordering you provided. And I am not aware if any DB allow users to customize comparison function for a particular data type.

Failing that, I see a few alternatives in solving your problem:

  1. Drop the ordering option, get the unsorted events and sort in python.
  2. Get the events with 2 queries. Get the unfinished events (end_time=NULL), and finished events (end_time!=NULL), this makes sense if business logic may require the separation of the 2 groups.
  3. If the ordering has to happen in DB. Add a default value to end_date, like "2099-01-01", which guarantees the correct ordering.

Upvotes: 1

Related Questions