Home > Blockchain >  How to dynamically set the sorting parameter order with null last in django API?
How to dynamically set the sorting parameter order with null last in django API?

Time:03-23

I am receiving sort_by and sort_order as query parameters into our Django API. I have the logic originally like this:

class Users:
    queryset = ...
    sort_by = self.request.query_params.get('sort_by')
    sort_order = self.request.query_params.get('sort_order')

    if sort_order == "desc":
        sort_by = "-"   sort_by
    
    def get_queryset(self):
        return queryset.order_by(sort_by, "id")

The issue I ran into is that when I sort by descending order by a specific parameter, the null values will show up first. I want all null values to be last no matter if I'm sorting asc or desc. I saw that there's a function from the Django docs here but that would mean that I have to have a different function call for whether it's ascending or descending which would make it not elegant:

if sort_order == 'desc':
    return queryset.order_by(F(sort_by).desc(nulls_last=True), "id")
else:
    return queryset.order_by(F(sort_by).asc(nulls_last=True), "id")

Is there a better way of doing this?

CodePudding user response:

if not sort_order:
   sort_order = "asc"
return queryset.order_by(getattr(F(sort_by),sort_order))(nulls_last=True), "id")

I think??

although im not sure thats more elegant than just using 2 calls...

im also not sure what order

queryset.order_by(F("-pk").asc()) would give? it might just be the same as order_by(F("pk").desc())?

I would probably just do something along the lines of

order_by_clause = F(sort_by).asc(nulls_last=True)
if sort_order == "desc":
   order_by_clause = F(sort_by).desc(nulls_last=True)
return queryset.order_by(order_by_clause,"id")

If it was me

  • Related