Django фильтрует объекты по CharField, содержащие не более двух слов - PullRequest
0 голосов
/ 24 мая 2018

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

class SearchLog(models.Model):
     query = models.CharField(max_length=512)
     datetime = models.DateTimeField(auto_now_add=True, db_index=True)

Чтобы получить все запросы, содержащие не более одного слова, я задаю этот набор запросов:

SearchLog.objects.exclude(query__contains=" ")

Я хочу получить запросы, которые содержат не более двух словесть ли вообще хоть с raw sql?

1 Ответ

0 голосов
/ 24 мая 2018

Для этого можно использовать регулярное выражение (регулярное выражение) .Это текстовый шаблон, который вы описываете.

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

^\S+(\s+\S+)?$

(но в зависимости от ситуациивам, возможно, придется немного его изменить).

\S обозначает непробельные символы (т.е. без пробела, табуляции, новой строки и т. д.).Мы повторяем такие символы один или несколько раз (с квантификатором +).Далее мы допускаем второе слово по выбору (это значение знака вопроса ? в конце).Это новое слово состоит из одного или нескольких последовательных пробелов (с \s+) и одного или нескольких непробельных символов (с \S+).Якоря (^) и доллар ($) обозначают начало и конец строки (без нее она будет соответствовать всему, что имеет хотя бы одно слово).Как уже говорилось, одной из проблем может быть то, что вы видите словом, поэтому на основании этих спецификаций вам, возможно, придется немного изменить регулярное выражение.

В случае, например, запросы без слов вообще должны бытьтакже мы должны изменить его на ^(\S+(\s+\S+)?)?$, но тогда строки с единственным интервалом по-прежнему не совпадают.Вы видите, что может быть трудно получить правильную модель полностью, поскольку она в основном зависит от того, что вы видите как « match », а что нет.

Вы можете проверить регулярное выражение с помощью regex101 .Соответствующие строки являются выделенными линиями.Строки с тремя или более словами выделены , а не , поэтому регулярное выражение исключит их.Вы можете использовать этот инструмент для проверки регулярных выражений и их изменения до тех пор, пока они не будут полностью соответствовать вашим требованиям.

Таким образом, мы можем фильтровать с помощью:

SearchLog.objects.filter(query<b>__regex=r'^\S+(\s+\S+)?$'</b>)

Регулярные выражения могут выполнять довольно сложные сопоставления,Однако в информатике существует известная « прокачка леммы для регулярных языков », которая указывает, что существуют определенные семейства шаблонов, которые могут не записываться как регулярные выражения (ну, на самом деле, естьсемейства шаблонов, которые не могут быть сопоставлены ни одной программой).Здесь это не имеет большого значения (я думаю), но регулярное выражение, таким образом, само по себе не способно соответствовать любому шаблону, который имеет в виду программист.

...