как отфильтровать условия 2 Q в запросе django?

#python #django #django-orm

Вопрос:

итак,у меня есть список всех мобильных телефонов, чей бренд является одним из входящих брендов. Будут введены нужные названия брендов. Количество записей неизвестно и может быть пустым. Если входные данные пусты, необходимо вернуть список всех мобильных телефонов.

Модель:

 from django.db import models


class Brand(models.Model):
    name = models.CharField(max_length=32)
    nationality = models.CharField(max_length=32)

    def __str__(self):
        return self.name


class Mobile(models.Model):
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
    model = models.CharField(max_length=32, default='9T Pro', unique=True)
    price = models.PositiveIntegerField(default=2097152)
    color = models.CharField(max_length=16, default='Black')
    display_size = models.SmallIntegerField(default=4)
    is_available = models.BooleanField(default=True)
    made_in = models.CharField(max_length=20, default='China')

    def __str__(self):
        return '{} {}'.format(self.brand.name, self.model)
 

запрос:

 from django.db.models import F, Q


def some_brand_mobiles(*brand_names):
    query = Mobile.objects.filter(Q(brand__name__in=brand_names) | ~Q(brand__name=[]))
    return query
 

Если входные данные пусты, будет возвращен список всех мобильных телефонов, но я не могу использовать *brand_names для возврата списка.

например

 query = Mobile.objects.filter(Q(brand_name_in=['Apple', 'Xiaomi']))
return query
 

и

 query = Mobile.objects.filter(~Q(brand__name=[]))
    return query
 

Оба этих условия работают только на примере, но это не проверяет оба условия с помощью функции, которую я написал.
как это исправить ?

Ответ №1:

Проще просто проверить список brand_names и отфильтровать, если он содержит хотя бы один элемент:

 def some_brand_mobiles(*brand_names):
    if brand_names:
        return Mobile.objects.filter(brand__name__in=brand_names)
    else:
        return Mobile.objects.all() 

Ответ №2:

Попробуйте это решение:

 def some_brand_mobiles(*brand_names):
    queryset = Mobile.objects.all()
    if brand_names:
        queryset = queryset.filter(brand__name__in=brand_names)
    return queryset
 

Таким образом, вы можете добавить больше фильтров на основе любого другого условия queryset .