Фильтр для нескольких значений поля в DRF - PullRequest
1 голос
/ 14 июля 2020

В Amazon вы можете фильтровать по нескольким брендам, например. Вы выбираете Nike, Puma, Adidas. В отправляемом обратно наборе запросов есть продукты, принадлежащие любой из этих марок.

, если у вас есть такая модель, как:

class Product(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    brand = models.CharField(max_length=100)

сериализатор, например:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product
        fields = "__all__"

вид, например:

class ProductViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.ProductSerializer
    permission_classes = [IsAuthenticated]
    filter_backends = [filters.ProductMultipleFilterBackend ]

файл filters.py:

from rest_framework import filters as drf_filters
from django_filters import rest_framework as df_filters

class MultipleField(MultipleChoiceField):
    def valid_value(self, value):   
        return True

class MultipleFilter(df_filters.MultipleChoiceFilter):
    field_class = MultipleField

class ProductMultipleFilterBackend(df_filters.FilterSet):
    brand = MultipleFilter(lookup_expr="icontains", field_name = "brand")
    search = MultipleFilter(lookup_expr="icontains", field_name = "description")

    class Meta:
        model = models.Product
        fields = ["brand", "search"]

приведенный выше код был тем, что я нашел здесь . Но ему примерно 5 лет, и может быть лучший способ, о котором я точно не знаю, и я получаю следующую ошибку в коде:

filter_queryset() takes 2 positional arguments but 4 were given

Какой будет структура URL-адресов для этих запросы: / someurl? brand = Nike, Adidas, Puma или / someurl? brand = [Nike, Adidas, Puma]

Заранее спасибо !!!!

1 Ответ

0 голосов
/ 14 июля 2020

Обычное поведение для multiple choice похоже на ?f=v1&f=v2, хотя вы можете передать правильный widget, чтобы изменить структуру URL-адреса по умолчанию на значение, разделенное запятыми, используя CSVWidget

from django_filters.fields import CSVWidget

class ProductMultipleFilterBackend(df_filters.FilterSet):
    brand = MultipleFilter(
                 lookup_expr="icontains", 
                 field_name = "brand",
                 <b>widget=CSVWidget</b>
            )
     ...

Затем, вы можете фильтровать, используя формат csv, например: url?brand=a,b

...