【问题标题】:Django_filter on an apiviewapiview 上的 Django 过滤器
【发布时间】:2020-06-28 17:19:54
【问题描述】:

我一直在尝试在 APIView 上使用 Django_filter,但它不起作用。我正在尝试在模型的某些字段上实现过滤器搜索。

下面是模型的设置方式

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'),

这就是我的结果的样子

请问,我怎样才能让 Django 过滤器在 APIView 上工作

【问题讨论】:

    标签: django django-rest-framework django-filter


    【解决方案1】:

    您似乎正试图通过使用APIView 来获得DRF ListAPIView 的相似 或精确 行为。在您的情况下,我建议使用 ListAPIView 而不是 APIView。

    from rest_framework import generics
    from django_filters import rest_framework as filters
    
    
    class ListUsersView(generics.ListAPIView):
        '''
        Gets all the users in the database
        '''
        queryset = User.objects.all()
        serializer_class = UserSerializer
        permission_classes = [AllowAny]
        filterset_class = UserFilter
        filter_backends = (filters.backends.DjangoFilterBackend,)

    要在 APIView 中添加过滤功能,

    class MyAPIViewKlass(APIView):
        filter_backends = (filters.DjangoFilterBackend,)
    
        def filter_queryset(self, queryset):
            for backend in list(self.filter_backends):
                queryset = backend().filter_queryset(self.request, queryset, self)
            return queryset
    
        def get(self, request, *args, **kwargs):
            base_qs = MyModel.objects.all()
            filtered_qs = self.filter_queryset(base_qs)
            serializer = MySerializer(filtered_qs, many=True)
            return Response(serializer.data)

    【讨论】:

    • 是的,我知道它适用于 generics.ListAPIView,但我试图通过 APIView 获得相同的行为,以防我以后想要自定义它。
    • 您的方法具有讽刺意味的是,您正试图将 APIView 类变为 ListView。 ListView 继承自 APIView,提供一些附加功能,如分页、过滤、序列化等
    • 也就是说,如果你给APIView类添加分页和过滤功能,它就变成了几乎一个ListView
    猜你喜欢
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2021-04-29
    • 2014-01-30
    相关资源
    最近更新 更多