djangodjango-rest-frameworkdjango-filter

get multiple query params with the same key in drf django-filter


I am going to use django-filter to perform filtering in Django models

everything is fine but i have two problems

1.In the url, I must send the brand name or do not send the brand name at all, if I send the brand name empty, an error will occur -> how can i fix it?

http://127.0.0.1:8000/api/products/filtered_data/?brand_name=nike -> correct

http://127.0.0.1:8000/api/products/filtered_data/ -> correct

http://127.0.0.1:8000/api/products/filtered_data/?brand_name= -> 
{
        "brand_name": [
            "Select a valid choice.  is not one of the available choices."
        ]
    }

2.To get multiple brands, I have to send the brand name several times, but I want to make it

possible to send the brand names with ','

http://127.0.0.1:8000/api/products/filtered_data/?brand_name=nike&brand_name=guchi -> i have to send brand names like this

http://127.0.0.1:8000/api/products/filtered_data/?brand_name=nike,guchi -> i want to send brand names like this

views.py:

class ProductFilter(filters.FilterSet)
    brand_name = filters.ModelMultipleChoiceFilter(queryset=Brand.objects.all(),)

    class Meta:
        model = Product
        fields = ["has_discount","brand_name","available"]

class filtered_data(ListAPIView):
    authentication_classes = []
    permission_classes = []
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filterset_class = ProductFilter

models.py:

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

    def __str__(self):
        return self.name


class Product(models.Model):
    category = models.ManyToManyField(Category, related_name='cat_product')
    name = models.CharField(max_length=200)
    has_discount = models.BooleanField(default=False)
    brand_name = models.Foreignkey(Brand,  on_delete = models.CASCADE)
    brand_image = models.ImageField(null=True,blank=True,upload_to='product')
    create = models.DateTimeField(auto_now_add=True)
    available = models.BooleanField(default=True)
    discount = models.IntegerField(blank=True, null=True)

Solution

  • There are two different ways to filter:

    1. If your query_params contain list of names then query like,

      you will send brand_name like this, it should be list

      http://127.0.0.1:8000/api/products/filtered_data/?**brand_name**=['nike,guchi']

      and your query will be like:

      queryset=Brand.objects.filter(brand_name__in=brand_name)

    2. If your query_params contain single name then query like,

      you will send brand_name like this

      http://127.0.0.1:8000/api/products/filtered_data/?brand_name='nike'

      and your queries will be different now its your choice:

      queryset=Brand.objects.filter(brand_name=brand_name) queryset=Brand.objects.filter(brand_name__exact=brand_name) queryset=Brand.objects.filter(brand_name__iexact=brand_name) queryset=Brand.objects.filter(brand_name__contains=brand_name)

    Let me know if you face any problem regarding my answer or anything else