Объединение нескольких фильтров в наборах запросов с помощью django-filter

Скажем, у меня есть следующие две модели Django:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    name = models.CharField(max_length=300)
    pages = models.IntegerField()
    author = models.ForeignKey(Author)

С django-filter, как я могу написать FilterSet, который позволяет мне фильтровать что-то вроде:

Author.objects.filter(
    (Q(book__name__contains='How') & Q(book__pages=100)) |
    (Q(book__name__contains='Why') & Q(book__pages=50))
)

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

Есть ли какой-нибудь стандартный способ решить эту проблему с помощью django-filter, или мне следует реализовать собственную логику фильтрации в представлении?


person janoliver    schedule 14.11.2016    source источник
comment
Как здесь будет выглядеть строка запроса запроса? Как бы вы различали два набора объектов Q, по которым вы хотите фильтровать?   -  person Sherpa    schedule 16.11.2016


Ответы (1)


Если вы хотите сохранить это в FilterSet, а не возвращать обратно в представление, лучше всего переопределить свойство qs и добавить туда логику фильтрации с несколькими значениями.

(Поле с пользовательским method обеспечивает проверку, но по-прежнему принимает только одно значение — так что вам все равно придется извлекать остальные из parent — поэтому переопределение qs кажется более понятным.)

person Carlton Gibson    schedule 16.11.2016
comment
Я так подумал и решил, что просто сделать это вручную в представлении со стандартной формой django будет более простым и читаемым решением. Тем не менее, ваш ответ по-прежнему правильный для django-filter, поэтому я его приму. - person janoliver; 16.11.2016
comment
Да, достаточно справедливо. Область применения Django Filter — это обычные проблемы с фильтрацией — для нестандартных все еще может потребоваться ручное решение. :-) - person Carlton Gibson; 16.11.2016