Django_filter на apiview - PullRequest
       8

Django_filter на apiview

0 голосов
/ 17 марта 2020

Я пытался использовать Django_filter на APIView, но он просто не работает. Я пытаюсь реализовать поиск по фильтру в некоторых полях модели.

ниже показано, как настраивается модель

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=250)
    picture = models.TextField(null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

class Skill(models.Model):
    name = models.CharField(max_length=60)
    subcategory = models.CharField(max_length=60, blank=True, null=True)
    created_on = models.DateTimeField(auto_now=True)
    updated_on = models.DateTimeField(auto_now_add=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING)

Настройка views.py также показана ниже.

from django_filters import rest_framework as filters


class UserFilter(filters.FilterSet):
    email = filters.CharFilter(lookup_expr='icontains')
    name = filters.CharFilter(lookup_expr='icontains')
    profiles__skills = filters.CharFilter(lookup_expr='icontains')

    class Meta:
        model = User
        fields = ('email', 'name', 'profiles__skills')


class ListUsersView(APIView, MyPaginationMixin):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
    filterset_class = UserFilter

    def get(self, request):
        page = self.paginate_queryset(self.queryset)

        if page is not None:
            serializer_context = {"request": request}
            serializer = self.serializer_class(page, context=serializer_context, many=True)
            return self.get_paginated_response(serializer.data)

и, наконец, мой serializer.py

class UserSerializer(serializers.ModelSerializer):
    slug = serializers.SlugField(read_only=True)

    class Meta:
        model = User
        fields = ('email', 'name', 'slug', 'picture')
        read_only_fields = ('email', 'name', 'slug',)

мой urls.py

path('users/', qv.ListUsersView.as_view(), name='list-users'),

так выглядит мой результат enter image description here

пожалуйста, как мне заставить фильтр Django работать на APIView

1 Ответ

1 голос
/ 26 марта 2020

Кажется, вы пытаетесь получить подобное или точное поведение DRF ListAPIView с помощью APIView. Я бы предложил использовать ListAPIView сверх APIView в вашем случае.

<b>from rest_framework import generics
from django_filters import rest_framework as filters</b>


class ListUsersView(<b>generics.ListAPIView</b>):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    filterset_class = UserFilter
    <b>filter_backends = (filters.backends.DjangoFilterBackend,)</b>

Чтобы добавить возможность фильтрации в APIView,

class MyAPIViewKlass(APIView):
    filter_backends = (filters.DjangoFilterBackend,)

    <b>def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset</b>

    def get(self, request, *args, **kwargs):
        <b>base_qs = MyModel.objects.all()
        filtered_qs = self.filter_queryset(base_qs)</b>
        serializer = MySerializer(filtered_qs, many=True)
        return Response(serializer.data)
...