50👍
As far as I’m aware, there’s no way to specify database-side ordering in this way as it would be too backend-specific. You may wish to resort to good old-fashioned Python sorting:
class Foo(models.Model):
name = models.CharField(max_length=128)
Foo.objects.create(name='a10')
Foo.objects.create(name='a1')
Foo.objects.create(name='a2')
ordered = sorted(Foo.objects.all(), key=lambda n: (n[0], int(n[1:])))
print ordered # yields a1, a2, 10
If you find yourself needing this kind of sorting a lot, I’d recommend making a custom models.Manager
subclass for your model that performs the ordering. Something like:
class FooManager(models.Manager):
def in_a_number_order(self, *args, **kwargs):
qs = self.get_query_set().filter(*args, **kwargs)
return sorted(qs, key=lambda n: (n[0], int(n[1:])))
class Foo(models.Model):
... as before ...
objects = FooManager()
print Foo.objects.in_a_number_order()
print Foo.objects.in_a_number_order(id__in=[5, 4, 3]) # or any filtering expression
39👍
@Jarret’s answer (do the sort in Python) works great for simple cases. As soon as you have a large table and want to, say, pull only the first page of results sorted in a certain way, this approach breaks (you have to pull every single row from the database before you can do the sort). At that point I would look into adding a denormalized “sort” field which you populate from the “name” field at save-time, that you can sort on at the DB-level in the usual way.
- [Django]-Fastest way to get the first object from a queryset in django?
- [Django]-">", "<", ">=" and "<=" don't work with "filter()" in Django
- [Django]-Form with CheckboxSelectMultiple doesn't validate
1👍
It depends on where you want to use it.
If you want to use it in your own templates, I would suggest to write a template-tag, that will do the ordering for you
In it, you could use any sorting algorithm you want to use.
In admin I do custom sorting by extending the templates to my needs and loading a template-tag as described above
- [Django]-How can I use redis with Django?
- [Django]-Create empty queryset by default in django form fields
- [Django]-How to create a custom decorator in Django?
0👍
If you have larger data sets and additionally use a SOLR backend (e.g. with Haystack):
Use solr.ICUCollationField
with the numeric=true
option as type for the sort fields. This will sort according to language and if numbers are present will sort the number part according to numeric rules instead of string sorting.
See:
https://cwiki.apache.org/confluence/display/solr/Language+Analysis#LanguageAnalysis-UnicodeCollation
http://www.solr-start.com/javadoc/solr-lucene/org/apache/solr/schema/ICUCollationField.html
- [Django]-What's the idiomatic Python equivalent to Django's 'regroup' template tag?
- [Django]-Django: Staff Decorator
- [Django]-Django settings per application – best practice?