2010-08-04 3 views
27

Je sais, je peux lancer une recherche insensible à la casse de DJango ORM. Comme,django-orm insensible à la casse par

User.objects.filter(first_name__contains="jake") 
User.objects.filter(first_name__contains="sulley") 
User.objects.filter(first_name__icontains="Jake") 
User.objects.filter(first_name__icontains="Sulley") 

Et aussi, je peux les récupérer comme

user_list = User.objects.all().order_by("first_name") 
# sequence: (Jake, Sulley, jake, sulley) 
user_list = User.objects.all().order_by("-first_name") # for reverse 
# sequence: (sulley, jake, Sulley, Jake) 

est-il un moyen direct pour la casse ?? d'extraction Comme dans Je veux une séquence comme

# desired sequence: jake, Jake, sulley, Sulley 

Sinon, alors suggère une meilleure façon de le faire. Merci d'avance.

Répondre

23

J'ai trouvé la solution à l'aide .extra

class MyModelName(models.Model): 
    is_mine = models.BooleanField(default=False) 
    name = models.CharField(max_length=100) 


MyModelName.objects.filter(is_mine=1).extra(\ 
    select={'lower_name':'lower(name)'}).order_by('lower_name') 

lien d'origine:

http://naorrosenberg.blogspot.fi/2011/04/django-models-orderby-charfield-case.html

+1

Cela ne fonctionnera pas lors de la relation de traversée, c'est-à-dire "name__something", mais vous pouvez le faire fonctionner avec la fonction Lower depuis django 1.8: 'depuis django.db.models.functions import Lower' et 'MyModelName.objects.order_by (Lower ('name_something')) 'ici c'est https://docs.djangoproject.com/fr/1.9/_modules/django/db/models/functions/#Lower – romainm

6

Ceci est pour postgresql, mais peut-être il sera utile pour d'autres bases de données aussi:

http://scottbarnham.com/blog/2007/11/20/case-insensitive-ordering-with-django-and-postgresql/

+0

Mais cela ne fonctionne pas avec d'autres DB de. Aussi, il deviendrait complexe si je devais commander sur des champs de tables jointes, non? – simplyharsh

+0

Avoir à accepter un plus utile. Merci. – simplyharsh

+0

Vous n'avez rien à accepter, si la réponse ne vous satisfait pas. Malheureusement, django ne fournit pas de mécanisme pour ce que vous voulez en ce moment. Vous pouvez essayer de travailler avec "extra" et ainsi essayer d'atteindre ce que vous voulez. Cela devrait fonctionner sur n'importe quel DB. Ou vous pouvez écrire un sql brut. – gruszczy

37

Depuis Django 1.8, il est possible avec:

from django.db.models.functions import Lower 
MyModel.objects.order_by(Lower('myfield')) 

https://code.djangoproject.com/ticket/6498

+0

Ceci est une meilleure solution pour les nouvelles versions de Django. Merci! – Chris

+0

Est-il possible d'utiliser Lower avec plusieurs colonnes? Je peux seulement sembler l'obtenir pour fonctionner avec une colonne. – Ben

+0

C'est possible: User.objects.order_by (Lower ('nom d'utilisateur'), ​​Lower ('email')) –