How do you order Django QuerySet results so that first item is the
exact match if using contains
or icontains
? Both solutions were proposed on the
django-users
mailing list.
Solution by Tom Evans, example is mine:
>>> from django.db.models import Q
>>> Package.objects.filter(
Q(name=Django) | Q(name__icontains=Django)
).extra(
select={'match' : 'name = "Django"'}
).order_by('-match', 'name')
[<Package: Django>, <Package: appomatic_django_cms>, <Package: appomatic_django_filer>,
<Package: appomatic_django_vcs>, <Package: BabelDjango>, <Package: BDD4Django>,
<Package: blanc-django-admin-skin>, <Package: bootstrap-django-forms>,
<Package: capistrano-django>, <Package: ccnmtldjango>, <Package: collective.django>,
<Package: csdjango.contactform>, <Package: cykooz.djangopaste>,
<Package: cykooz.djangorecipe>, <Package: d51.django.virtualenv.test_runner>,
<Package: django-4store>, <Package: django-503>, <Package: django-absolute>,
<Package: django-abstract-templates>, <Package: django-account>,
'...(remaining elements truncated)...']
>>>
Another one:
I'm not sure this is the right way, but you could drop the Q objects, use only icontains and sort by the length of 'name'
Gabriel https://groups.google.com/d/topic/django-users/OCNmIXrRgag/discussion
>>> packages = [p.name for p in Package.objects.filter(name__icontains='Dancer')]
>>> sorted(packages, key=len)
[u'Dancer', u'Dancer2', u'breakdancer', u'Task::Dancer', u'App::Dancer2', u'Dancer::Routes',
u'DancerX::Routes', u'DancerX::Config', u'Task::DWIM::Dancer', u'Dancer::Plugin::CDN',
u'Dancer::Plugin::Feed', u'Dancer::Plugin::LDAP', u'Dancer::Plugin::Lucy',
'...(remaining elements truncated)...']
>>>
That's all folks. If you have other more interesting sorting needs please comment below. Thanks!
Comments !