Подтвердить что ты не робот

Фильтр django на основе длины текста

Я хотел бы отфильтровать мою модель на основе длины текста Что-то вроде

MyModel.objects.filter(len(text) > 10)

где текст является Char или текстовым полем в модели MyModel

4b9b3361

Ответ 1

Было бы намного лучше и быстрее, если бы вы просто добавили столбец, который предварительно вычисляет (запоминает) длину текста.

например.

class MyModel(models.Model):
    text = models.TextField()
    text_len = models.PositiveIntegerField()

     def save(self, *args, **kwargs):
         self.text_len = len(self.text)
         return super(MyModel, self).save(*args, **kwargs)

MyModel.objects.filter(text_len__gt = 10)     # Here text_len is pre-calculated by us on `save`

Ответ 2

Для Django >= 1.8 вы можете использовать Функция длины, которая является @Pratyush CHAR_LENGTH() под капотом для MySQL или LENGTH() для некоторых других баз данных:

from django.db.models.functions import Length
qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter(
    text_len__gt=10)

Ответ 3

Другой способ:

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

Это может использоваться там, где длина текста больше 255 символов.

Ответ 4

Вы можете использовать фильтр регулярных выражений для поиска текста определенной длины:

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

Предостережение: для MySQL максимальное значение длины - 255. В противном случае создается исключение:

DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")

Ответ 5

Хорошее решение для Django >= 1.9 возможно благодаря регистрации встроенной функции Length в качестве Преобразования для CharField поиска, (см. точно такой же пример в документах для Length as a transform)

from django.db.models import CharField
from django.db.models.functions import Length

CharField.register_lookup(Length, 'length')

result = MyModel.objects.filter(text__length__gt=10)

Он корректно работает для всех бэкендов, скомпилированных LENGTH() для большинства бэкэнд и CHAR_LENGTH() для MySQL. Затем он регистрируется для всех подклассов CharField автоматически, например. для EmailField. TextField необходимо зарегистрировать отдельно. Безопасно регистрировать имя "длина", потому что имя трансформирования никогда не может быть затенено или затенено одинаковым именем поля или связанным с ним именем поля.

Единственным недостатком может быть головоломка для чтения: откуда появилась "длина"? (Поиск является глобальным, но то же самое может быть, к счастью, безопасно зарегистрировано повторно в большем количестве модулей, если оно полезно для удобства чтения, без каких-либо возможных накладных расходов во время выполнения запроса.)

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

Ответ 6

Я бы решил проблему на вашем сервере приложений, а не облагал налоговую базу данных. Вы можете сделать это:

models_less_than_ten = []
mymodel = MyModel.objects.all()
for m in mymodel:
    if len(m.text) > 10:
          models_less_than_ten.append(m)