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 - Как переименовать поле модели с помощью юга?
  • Изменение Южного миграционного справочника
  • юг: не может ALTER TABLE, поскольку он имеет ожидающие события триггера
  • из моделей импорта django.db, миграции ImportError: невозможно импортировать имена миграции
  • Перенос базы данных на производство django
  • Django South - превращение поля null = True в поле null = False
  • Django & South: добавление нового поля, но DatabaseError происходит, «таблица уже существует»
  • Почему мои южные миграции не работают?
  • Юг: выполните миграцию для столбца, который является как уникальным, так и недействительным
  • django south migration, не устанавливает значение по умолчанию
  • Джанго-юг не обнаруживает изменения БД
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.