Il existe un autre moyen d'ajouter la fonctionnalité de nullités gérées à Django < v1.11 avec le style Django v1.11 :
from my_project.utils.django import F
MyModel.objects.all().order_by(F('price').desc(nulls_last=True))
# or
MyModel.objects.all().order_by(F('price').desc().nullslast())
Cons :
- Migration facile vers Django 1.11
- Nous n'entrons pas dans les détails du compilateur de requêtes.
Pour ce faire, nous devons surcharger les classes django.db.models.F et django.db.models.expressions.OrderBy :
from django.db.models import F as DjangoF
from django.db.models.expression import OrderBy as DjangoOrderBy
class OrderBy(DjangoOrderBy):
def __init__(self, expression, descending=False, nulls_last=None):
super(OrderBy, self).__init__(expression, descending)
self.nulls_last = nulls_last
...
def as_sql(self, compiler, connection, template=None, **extra_context):
...
ordering_value = 'DESC' if self.descending else 'ASC'
if self.nulls_last is not None:
nulls_value = 'LAST' if self.nulls_last else 'FIRST'
ordering_value += ' NULLS ' + nulls_value
placeholders = {
'expression': expression_sql,
'ordering': ordering_value,
}
...
def nullslast(self):
self.nulls_last = True
def nullsfirst(self):
self.nulls_last = False
class F(DjangoF):
...
def asc(self, nulls_last=None):
return OrderBy(self, nulls_last=nulls_last)
def desc(self, nulls_last=None):
return OrderBy(self, descending=True, nulls_last=nulls_last)