django-orm без учета регистра

Я знаю, что могу запустить поиск без учета регистра в DJango ORM. Нравиться,

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")

А также я могу получить их как

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)

Есть ли прямой способ выборки без учета регистра ?? Как в, я хочу последовательность как

# desired sequence: jake, Jake, sulley, Sulley

Если нет, предложите лучший способ сделать это. Заранее спасибо.


person simplyharsh    schedule 04.08.2010    source источник


Ответы (4)


Этот ответ устарел, проверьте решение ниже с django 1.8 ->

Я нашел решение, используя .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')

исходная ссылка:

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

person Troyhy    schedule 19.08.2012
comment
Это не сработает при обходе отношения, например name__something, однако вы можете заставить его работать с функцией Lower, поскольку django 1.8: 'from django.db.models.functions import Lower' и 'MyModelName.objects.order_by (Lower (' name_something '))' здесь это docs.djangoproject. com / en / 1.9 / _modules / django / db / models / - person romainm; 26.02.2016

Начиная с Django 1.8 это возможно:

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

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

person uri.z    schedule 29.12.2015
comment
Это лучшее решение для новых версий Django. Спасибо! - person Chris; 25.02.2017
comment
Можно ли использовать Lower с несколькими столбцами? Я могу заставить его работать только с одним столбцом. - person Ben; 16.06.2017
comment
Возможно: User.objects.order_by (Нижний ('имя пользователя'), Нижний ('электронная почта')) - person uri.z; 19.06.2017
comment
models.py class Meta: ordering = [Lower ('name')] - person Alex Winkler; 21.09.2020
comment
для использования в порядке убывания: MyModel.objects.order_by (Lower ('myfield'). desc ()) - person Dre; 08.03.2021

Это для postgresql, но, возможно, будет полезно и для других баз данных:

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

person gruszczy    schedule 04.08.2010
comment
Но это не сработает с другими БД. Также было бы сложно, если бы мне нужно было заказывать поля из объединенных таблиц, верно ?? - person simplyharsh; 05.08.2010
comment
Не нужно ничего принимать, если ответ вас не устраивает. К сожалению, django не предоставляет механизма для того, что вы хотите прямо сейчас. Вы можете попробовать работать с extra и таким образом добиться желаемого. Это должно работать на любом db. Или вы можете написать необработанный sql. - person gruszczy; 05.08.2010

Давайте рассмотрим пример, в котором вам нужно выполнить нечувствительный к регистру порядок в поле first_name из модели User.

# Importing the Lower Function
from django.db.models.functions import Lower


#For ordering by Ascending order
User.objects.all().order_by(Lower('first_name'))

#For ordering by Descending order
User.objects.all().order_by(Lower('first_name').desc())

Функция Lower преобразует все значения first_name в нижний регистр, а затем упорядочивает их соответствующим образом.

person Ranjan MP    schedule 16.05.2021