#33543: The behaviour of nulls_first and nulls_last is surprising and confusing.
-------------------------------------+-------------------------------------
               Reporter:  Gordon     |          Owner:  nobody
  Wrigley                            |
                   Type:             |         Status:  new
  Uncategorized                      |
              Component:  Database   |        Version:  3.2
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Consider the following:

 {{{
 In [11]: [tv.published_at for tv in
 TemplateVersion.objects.order_by(F("published_at").desc(nulls_first=True))]
 Out[11]:
 [None,
  datetime.datetime(2022, 2, 25, 13, 0, 12, 91916, tzinfo=<UTC>),
  datetime.datetime(2022, 2, 21, 10, 18, 0, 169248, tzinfo=<UTC>)]

 In [12]: [tv.published_at for tv in
 TemplateVersion.objects.order_by(F("published_at").desc(nulls_first=False))]
 Out[12]:
 [None,
  datetime.datetime(2022, 2, 25, 13, 0, 12, 91916, tzinfo=<UTC>),
  datetime.datetime(2022, 2, 21, 10, 18, 0, 169248, tzinfo=<UTC>)]

 In [13]: [tv.published_at for tv in
 TemplateVersion.objects.order_by(F("published_at").desc(nulls_last=True))]
 Out[13]:
 [datetime.datetime(2022, 2, 25, 13, 0, 12, 91916, tzinfo=<UTC>),
  datetime.datetime(2022, 2, 21, 10, 18, 0, 169248, tzinfo=<UTC>),
  None]

 In [14]: [tv.published_at for tv in
 TemplateVersion.objects.order_by(F("published_at").desc(nulls_last=False))]
 Out[14]:
 [None,
  datetime.datetime(2022, 2, 25, 13, 0, 12, 91916, tzinfo=<UTC>),
  datetime.datetime(2022, 2, 21, 10, 18, 0, 169248, tzinfo=<UTC>)]
 }}}

 Observe how `nulls_first=False` still puts the nulls first.

 This happens because they both default False and when they are both False
 it lets the DB decide.

 This is surprising behaviour, it also makes changing the null positioning
 based on a variable more awkward than it needs to be.

 I think it would be better if they defaulted to None, let the DB decide
 when both are None and when one is not None do the ordering that implies.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33543>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.ed6712ec9892973565c7bed1b4240074%40djangoproject.com.

Reply via email to