【问题标题】:Filtering querysets in Django Rest Framework在 Django Rest Framework 中过滤查询集
【发布时间】:2020-09-25 20:53:17
【问题描述】:

今天我的行为很奇怪。我在我的用户视图集中添加了一个自定义 mixin,以按用户名和密码以及其他字段过滤用户。代码如下所示:

class MultipleFieldLookupMixin(object):
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            if field in self.kwargs.keys(): # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        return obj


class UserView(MultipleFieldLookupMixin, viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_fields = ['username', 'pwd', 'token_confirm', 'email', 'token_cng_pwd']

我希望列表操作能够过滤每个给定参数中的查询集(如果没有可用参数则为 None,如果所有参数可用则为 all)。

但列表端点继续向我显示每个用户,而不过滤它们。

我哪里错了?我必须手动设置过滤器后端吗?我在做一些愚蠢的错误吗? 非常感谢

也许我必须将这些参数放在 urls.py 中?

我没有更改 urls.py,但它抛出了一个异常:

router.register('user', views.UserView)
router.register('user/username/{username}/', views.UserView, username = 'username')
router.register('user/username/{username}/pwd/{pwd}/', views.UserView, username = 'username', pwd = 'pwd')
router.register('user/email/{email}/', views.Userview, email = 'email')
router.register('user/token_confirm/{token_confirm}/', views.UserView, token_confirm = 'token_confirm')
router.register('user/token_cng_pwd/{token_cng_pwd}/', views.UserView, token_cng_pwd = 'token_cng_pwd')

例外:

router.register('user/username/{username}', views.UserView, username = 'username')
TypeError: register() got an unexpected keyword argument 'username'

我不是要过滤查询,但我会试一试!

【问题讨论】:

标签: django python-3.x django-rest-framework


【解决方案1】:

get_object 返回单个对象实例。 文档字符串说您可以查找具有一个或多个字段(属性)的单个对象。

obj = get_object_or_404(queryset, **filter)

过滤列表使用django_filters它正是为此目的而构建的,它非常强大且易于使用。

from rest_framework import routers, serializers, viewsets
from rest_framework import filters
import django_filters.rest_framework
from .serializer import UserSerializer, User



class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [django_filters.rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['username' , 'first_name']
    search_fields = ['username']
    ordering_fields = ['username']
    ordering = ['username']

如果您仍然好奇或想为列表视图构建自定义过滤,请覆盖视图集的get_queryset() 方法。

【讨论】:

    猜你喜欢
    • 2019-03-20
    • 2018-07-28
    • 2013-05-21
    • 2021-09-21
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2016-09-30
    • 2016-08-13
    相关资源
    最近更新 更多