@Untiwe

Как сделать динамическое количество Q запросов?

На моем сайте есть поиск по постам. Пользователь вводит ключевое слово и с помощью checkbox может выбрать в каком поле это искать, "автор", "имя поста", "текст поста"
При всех включенных checkbox получится так
filters = Q(author=keyword) | Q(name=keyword) | Q(text=keyword)
Posts.objects.filter(filters)

При всех выключенных checkbox, будет так, но это вообще ошибка(хочется что бы выдавал просто все посты)
filters#переменная не определена, ошибка
Posts.objects.filter(filters)


Можно это реализовать нагромоздив if else но думаю, есть способ лучше
  • Вопрос задан
  • 64 просмотра
Решения вопроса 1
@gimntut
Untiwe я доработал твой код.
Вся хитрость в 2х звёздочках **
def get_queryset(self):
        if not self.request.GET:
            return Posts.objects.all()#если нет параметров, просто возвращаем все посты
        keyword = self.request.GET.get('key')#получаем ключевое слово
        filters = Q()#создаем первый объект Q, что бы складывать с ним другие
        for key in ['author', 'name', 'text']:
                value = self.request.GET.get(key)
                if value:
                        filters |= Q(**{f'{key}__icontains': keyword})
        return Posts.objects.filter(filters)
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@bacon
просто с if'ами, без else, так же можно for по списку checkbox
Ответ написан
@Untiwe Автор вопроса
Ответ Dr. Bacon не совсем понял, но сделал вот так. Если кому надо, у меня идет определение класса от ListView и определение метода get_queryset. Данный пример не работает сам по себе, но показывает идею

def get_queryset(self):
        if not self.request.GET:
            return Posts.objects.all()#если нет параметров, просто возвращаем все посты

        keyword = self.request.GET.get('key')#получаем ключевое слово
        author= self.request.GET.get('author')#если параметра нет, get() вернет None что равняется False
        name = self.request.GET.get('name')#если параметра нет, get() вернет None что равняется False
        text = self.request.GET.get('text')#если параметра нет, get() вернет None что равняется False
        filters = Q()#создаем первый объект Q, что бы складывать с ним другие
        if author:
            filters |= Q(name__icontains=keyword )
        if name:
            filters |= Q(name__icontains=keyword )
        if text:
            filters |= Q(name__icontains=keyword )
        
        return Posts.objects.filter(filters)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы