Django – выбор запроса фильтра по длине значения CharField

Учитывая, что у меня есть устаревшая модель с CharField модели CharField или CharField например:

 class MyModel(models.Model): name = models.CharField(max_length=1024, ...) ... 

Мне нужно сделать миграции, чтобы он имел максимальную max_length max. 255. Сначала я пишу datamigration чтобы любые значения с длиной более 255 символов адаптировали предстоящую schemamigration для фиксации максимальной длины столбца, что я буду делать сразу после этого.

Проблема в том, что у меня очень большой набор данных, и я знаю, что не все строки содержат значение длиннее 255 символов для MyModel.name и я бы хотел рассмотреть для моей миграции только тех, кто это делает.

Есть ли способ (с) django ORM фильтровать только объекты, которые удовлетворяют этому условию? Что-то вроде:

 MyModel.objects.filter(name__len__gte=255) 

было бы здорово, но я считаю, что это невозможно, или, по крайней мере, это не так просто.

Кто-нибудь знает какой-либо способ выполнить этот запрос?

Благодаря!

2 Solutions collect form web for “Django – выбор запроса фильтра по длине значения CharField”

«Последние» версии Django имеют встроенный django.db.models.functions.Length lookup / transform, поэтому вы можете сделать:

 MyModel.objects.annotate(length=Length('text')).filter(length__gt=254) 

См. https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#length

Старый ответ:

Я думаю, у вас есть варианты:

Использование «extra» в наборе запросов:

 MyModel.objects.extra(where=["CHAR_LENGTH(text) > 254"]) 

Или злоупотребляя поисками Regex, я предполагаю, что это будет медленнее:

 MyModel.objects.filter(text__regex = r'^.{254}.*') 

Если вы обнаружите, что используете много дополнительных и регулярных выражений, следуя предложениям @ BBT, я пошел вперед и внедрил преобразование следующим образом:

 # utils.db from django.db.models import Transform from django.db.models import CharField class CharacterLength(Transform): lookup_name = 'len' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return "LENGTH(%s)" % lhs, params CharField.register_lookup(CharacterLength) 

После этого я мог бы выполнить каскадный поиск по «mycolname» следующим образом:

 from utils.db import * queryset.filter(mycolname__len__gte=10) 
  • Ошибка Django South: AttributeError: объект DateTimeField не имеет атрибута 'model'`
  • Django South: как я могу получить доступ к моделям в подпакетах при миграции
  • Изменение столбца модели Django по умолчанию с использованием юга
  • Миграции Django - можно ли использовать Юг в середине проекта?
  • Какой порядок миграции юг следует в разных приложениях?
  • Перенос базы данных на производство django
  • Django & South: добавление нового поля, но DatabaseError происходит, «таблица уже существует»
  • Python South не собирает изменения, внесенные в метод add_to_class ()
  • Python - лучший язык программирования в мире.