在Django rest框架中自定义详细路由的权限和响应

时间:2017-11-30 14:23:49

标签: django django-rest-framework django-views

概述 - 我正在创建一个Django REST API,它从嵌套的url路由返回数据。到目前为止,我发现这样做的最好方法是手动将url正则表达式添加到urls.py,然后在我的视图中使用@detail_route来检索已过滤的序列化数据。

现在我有用户对象和目标对象,需要基于身份验证等的不同数据响应......

如何自定义详细路线以执行此操作?例如:

如果用户是管理员,他们可以使用'帖子' / api / v2 / users url中的方法。如果他们未经过身份验证,则会收到错误请求400响应。

如果用户是管理员,他们可以使用' get'检索所有用户名,电子邮件和密码的方法,但如果不是,则只能获取用户名。

urls.py

urlpatterns = [

    url(r'^api/v2/users/$',
        UserViewSet.as_view({'get': 'users', 'post': 'users', 'put': 'users',
                             'patch': 'users', 'delete': 'users'}),
        name='user_list'),

    url(r'^api/v2/user/(?P<uid>\d+)/goals/$',
        UserViewSet.as_view({'get': 'user_goals', 'post': 'user_goals', 'put': 'user_goals',
                             'patch': 'user_goals', 'delete': 'user_goals'}),
        name='user_goals_list'),
]

serializers.py

class GoalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goal
        fields = ('id', 'user_id', 'name', 'amount',
                  'start_date', 'end_date', )


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'email', 'id', 'password')
        read_only_fields = ('id', )
        extra_kwargs = {'password': {'write_only': True}}

views.py

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = serializers.UserSerializer

    @detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
    def users(self, request):
        users = User.objects.all()
        serializer = serializers.UserSerializer(
            users, many=True
        )
        return Response(serializer.data)

    @detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
    def user_goals(self, request, uid):
        goals = Goal.objects.filter(user_id=uid)
        serializer = serializers.GoalSerializer(
            goals, many=True
        )
        return Response(serializer.data)

    @detail_route(methods=['get', 'post', 'delete', 'put', 'patch', ])
    def user_goal_detail(self, request, uid, gid):
        goal = Goal.objects.filter(user_id=uid, id=gid)
        serializer = serializers.GoalSerializer(
            goal, many=True
        )
        return Response(serializer.data)

1 个答案:

答案 0 :(得分:4)

就嵌套路由而言,我建议您看一下drf-nested-routers软件包或类似的软件包,它会使您的路由工作变得更轻松,请研究SimpleRouter和{{ 1}}类。

  

如果用户是管理员,则可以在/ api / v2 / users网址中使用“ post”方法。如果未通过身份验证,则会收到错误的请求400响应。

NestedSimpleRouter装饰器可以收到一个@detail_route参数,您可以在其中指定执行声明的动作所需的权限,就像您使用的permission_classes一样。

但是,您的示例显示了ViewSet模型的ModelViewSet,这意味着您已经暴露了多个动作,以及多个与User相关的奖金(GenericViewSet,{ {1}}等)

get_serializer

例如,如果您要执行get_object,可以通过路由器或class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): """ A viewset that provides default `create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()` actions. """ pass 上的GET /api/v2/users/进行链接,则可以覆盖{'get': 'list'}基于用户的方法:

urls.py

在这种情况下,还可以通过允许任何人使用get_serializer_class来使用def get_serializer_class(self): """ Return the class to use for the serializer. Defaults to using `self.serializer_class`. You may want to override this if you need to provide different serializations depending on the incoming request. (Eg. admins get full serialization, others get basic serialization) """ assert self.serializer_class is not None, ( "'%s' should either include a `serializer_class` attribute, " "or override the `get_serializer_class()` method." % self.__class__.__name__ ) return self.serializer_class 的{​​{1}}参数,否则检查管理员状态:

permission_classes

我可能聚会晚了,但是希望这对以后的其他人有帮助。