Source code for django_reorder.reorder

from django.db.models import Case, IntegerField, Value, When


class BEFORE:
    pass


class AFTER:
    pass


[docs]def reorder(_default=AFTER, _reverse=False, **kwargs): """ Return a database expression that can be used in an order_by() so that the queryset will be sorted according to the order of values given. """ if not 0 < len(kwargs) <= 1: raise TypeError("reorder() takes one non-optional keyword argument") fieldname, new_order = kwargs.popitem() if _default is BEFORE: _default = -1 elif _default is AFTER: _default = len(new_order) whens = [When(**{fieldname: v, 'then': i}) for i, v in enumerate(new_order)] casewhen = Case(*whens, default=Value(_default), output_field=IntegerField()) if _reverse: return casewhen.desc() else: return casewhen.asc()
[docs]def null_first(fieldname): """ Return a database expression that can be used in an order_by() close so that rows whose `fieldname` is NULL are sorted at the beginning. """ return reorder(_default=AFTER, **{fieldname: [None]})
[docs]def null_last(fieldname): """ Similar to null_first but NULL rows are sorted at the end. """ return reorder(_default=BEFORE, **{fieldname: [None]})