Учитывая класс:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
Возможно ли, и если да, то как, иметь QuerySet, который фильтрует на основе динамических аргументов? Например:
# Instead of:
Person.objects.filter(name__startswith='B')
# ... and:
Person.objects.filter(name__endswith='B')
# ... is there some way, given:
filter_by = '{0}__{1}'.format('name', 'startswith')
filter_value = 'B'
# ... that you can run the equivalent of this?
Person.objects.filter(filter_by=filter_value)
# ... which will throw an exception, since `filter_by` is not
# an attribute of `Person`.
python
django
django-models
Брайан М. Хант
источник
источник
Упрощенный пример:
В приложении для опроса Django я хотел список выбора HTML, показывающий зарегистрированных пользователей. Но поскольку у нас 5000 зарегистрированных пользователей, мне нужен был способ отфильтровать этот список по критериям запроса (например, просто люди, которые прошли определенный семинар). Чтобы элемент опроса можно было повторно использовать, мне нужно, чтобы человек, создающий вопрос опроса, мог прикрепить эти критерии к этому вопросу (не хочу жестко кодировать запрос в приложении).
Решение, которое я придумала, не на 100% удобное для пользователя (для его создания требуется помощь технического специалиста), но оно действительно решает проблему. При создании вопроса редактор может ввести словарь в настраиваемое поле, например:
Эта строка хранится в базе данных. В коде представления он возвращается как
self.question.custom_query
. Значением этого является строка, которая выглядит как словарь. Мы превращаем его обратно в настоящий словарь с помощью eval (), а затем помещаем его в набор запросов с помощью ** kwargs:источник
eval()
при импорте пользователей - плохая идея, даже если вы полностью доверяете своим пользователям. Здесь лучше использовать поле JSON.Django.db.models.Q - это именно то, что вам нужно в стиле Django.
источник
Q(**filters)
, если вы хотите динамически создавать объекты Q, вы можете поместить их в список и использовать.filter(*q_objects)
или использовать побитовые операторы для объединения объектов Q.Действительно сложные формы поиска обычно указывают на то, что более простая модель пытается найти выход.
Как именно вы ожидаете получить значения для имени столбца и операции? Где Вы получаете значение ?
'name'
'startswith'
Форма "поиска"? Вы собираетесь - что? - выбрать имя из списка имен? Выбрать операцию из списка операций? В то время как открытый, большинство людей находят это запутанным и трудным в использовании.
Сколько столбцов имеют такие фильтры? 6? 12? 18?
Специальные кнопки фильтра. Подожди ... Так работает админ Django. Специальные фильтры превращаются в кнопки. И тот же анализ, что и выше, применяется. Несколько фильтров имеют смысл. Большое количество фильтров обычно означает своего рода нарушение первой нормальной формы.
Много подобных полей часто означает, что должно быть больше строк и меньше полей.
источник