I want to order a QuerySet by a charfield with numbers in it. I have this code:
MyTable.objects.all().order_by('my_char_field')
There are some examples of "my_char_field":
"ver3", "ver10", "x5.1 (1)", "ver4", "x5.1 (2)"
The result of the order with the code above is:
"ver10", "ver3", "ver4", "x5.1 (1)", "x5.1 (2)"
But the order that I want is:
"ver3", "ver4", "ver10", "x5.1 (1)", "x5.1 (2)"
How can I get the natural order?
It seems more like a data storage issue. It becomes much easier if you change your data structure
version_type = models.CharField()
version_num = models.FloatField()
version_revision = models.SmallIntegerField(null=True)
unique_together = [('version_type', 'version_num', 'version_revision')]
.order_by('version_type', 'version_num', 'version_revision')
This would also solve your next issue of "how can I efficiently get all versions of type 'ver'?"
While it's possible to fetch and do the sorting in the client side, you can also use the Substr function to do this at the server side.
from django.db.models.functions import Substr
MyTable.objects.all().order_by(Substr('my_char_field',3))
Update:
I was working on another update to the answer, when the question was updated yet again!! The following is not complete, but you can build on it.
MyTable.objects.annotate(
sort_field=Case(
When(my_char_field__start_with='ver', Then=Substr(my_char_field, 3)),
When(my_char_field__start_with='x', Then=Substr(my_char_field, 1)),
default=my_char_field,
)
).order_by('sort_field')
You will need to use the Cast function as well to cast the sort_field to int. This is going to be one long query!!
I have a CharField with a name field, which has mixed (int+string) values, for example. "a1", "f65", "P", "55" etc ..
Solved the issue by using the sql cast (tested with postgres & mysql), first, I try to sort by the casted integer value, and then by the original value of the name field.
parking_slots = ParkingSlot.objects.all().extra(
select={'num_from_name': 'CAST(name AS INTEGER)'}
).order_by('num_from_name', 'name')
This way, in any case, the correct sorting works for me.
Just as @AKS mentioned, It could be inefficient to do the sorting in memory. As soon as you have a large table and you want to pull only the first page of results sorted. Then you have to pull every single row from the database before you can do the sort.
Something From Vem3456 to Vem6543
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.