how to filtered 2 Q conditions in query django?

Viewed 89

so,i have a List of all mobile phones whose brand name is one of the incoming brands. The desired brand names will be entered. The number of entries is unknown and may be empty. If the input is empty, the list of all mobile phones must be returned.

model:

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)

query:

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

If the input is empty, the list of all mobile phones will be returned, but i cant use *brand_names to return the list.

for example

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

and

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

Both of these conditions work by example alone, but it does not check both conditions with the function I wrote. how to fix it ?

2 Answers

It is simpler to just check the list of brand_names and filter if it contains at least one element:

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

Try this solution:

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

In that way you can add more filters based on any other condition over the queryset.

Related