Sorting django-mptt record by complex string field as number

18 Views Asked by At

I'm using django-mptt to build a hierarchical structure. There is a field "task_id", that represents task id, in the following format "task.subtask.subtask", number of subtasks is infinite.

To sort tasks, I'm using standard code order_insertion_by = ['task_id']

It works well, but the fields are sorted as string, i.e. 1.10, 1.2, 1.3, etc.

How can I make them sort as a number instead, so it will go 1.2, 1.2, 1.10?

1

There are 1 best solutions below

1
AKX On

Strings are lexicographically sorted, and 1.10 comes before 1.2, so you'll need an order_insertion_by that's lexicographically sortable.

The simplest would be to pad task_id's elements to e.g. 5 digits (if you can always trust you'll never have more than 99999 elements per level), and concatenate them since you know each element is always 5 digits long, you don't need separators, so the identifier could be e.g. 0000100010, etc. (This is coincidentally pretty much what django-treebeard's materialized path trees do.) You could also save some space by using e.g. base36 (0-9a-z) "numbers" instead, in which case e.g. you could use 4 characters for 36**4 = 1 679 616 options, or base62 (0-9a-zA-Z), etc.

Since it looks like order_insertion_by needs to refer to a concrete field, you can't get by with a sortable Python property, so you'd need a new (computed, cached) field for that lexicographically sortable task_id.