| published by | Software Crafts |
|---|---|
| in blog | Software Crafts |
| original entry | Efficient Django Query Challenge |
Last week I was tasked with implementing a sort functionality on one of my clients projects. The sorting was to be done on a time field associated with an item. However, in the current state, many existing items would all hold the same time leading to undefined behaviour when swapping items around to change the order.
Therefore to solve this undefined behaviour I updated the time to reflect the originial order before doing any swaps. This means a queryset with 4 items in it for a time of say 13:00, would get updated to 13:00, 13:01, 13:02, 13:03. I tried to do this as a query to begin with before resorting to a python implementation below:
ODD_SORTING = 3
if unsorted_queryset.count() >= ODD_SORTING:
dup_times = (
unsorted_queryset.values("time")
.annotate(Count("time"))
.filter(time__count__gte=ODD_SORTING)
)
if dup_times.exists():
for dtime in dup_times:
for idx, item in enumerate(unsorted_queryset.filter(time=dtime["time"])):
item.time = item.time.replace(minute=item.time.minute + idx)
item.save()
I'm open to any suggestions to make this more efficient, it works but I would prefer to remove those for loops. I think something could be done with a window function to get the row number which then forms the offset, but I could be completely wrong having not needed window functions myself before.
Like I said, do let me know how you would improve this.