DRF - 使用视图类进行自定义URL设计?

时间:2016-11-03 16:55:24

标签: django rest django-rest-framework

我想在django rest框架中为User模型实现以下URL设计(基于githubs的REST api):

# get authenticated user (the currently logged in user):
#
#   GET user/
#
# update authenticated user:
#
#   PATCH user/
#
# get single user (will only return instructors)
#
# GET user/:username
#
# get all users (will only return instructors)
#
# GET users/

给定User模型,我有以下标准序列化器:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.MyUser
        fields = '__all__'

我可以使用基于函数的视图为每个URL实现url路由,但是DRF提供了许多基于类的视图和路由器,我想知道是否有更简洁的方法来实现它?

2 个答案:

答案 0 :(得分:0)

基本上,您可以创建一个视图子类generics.GenericAPIView,并为CURD添加mixins,如下面的代码:

urls.py

url(r'^/user/(?P<pk>\d+)/detail/$', UserDetailView.as_view(), name='user_detail'),
url(r'^/user/(?P<pk>\d+)/update/$', UserDetailView.as_view(), name='user_update'),
url(r'^/user/list/$', UserListView.as_view(), name='user_list'),

views.py

from rest_framework import mixins
from rest_framework import generics

class UserListView(mixins.ListModelMixin,
                   generics.GenericAPIView):
    queryset = MyUser.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

class UserDetailView(mixins.RetrieveModelMixin,
                     mixins.UpdateModelMixin,
                     mixins.DestroyModelMixin,
                     generics.GenericAPIView):
    queryset = MyUser.objects.all()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)

如果您需要更多控制逻辑,您可以:

  1. [用户列表]:覆盖get_queryset中的UserListView,并提供逻辑以过滤用户并返回查询集。
  2. [获取用户详细信息]:与上述相同,但覆盖get_queryset
  3. 中的UserDetailView
  4. [补丁用户]:覆盖partial_update中的UserDetailView以提供更新逻辑。
  5. 总之,mixins是您开始在DRF上创建更通用的基于类的视图的好地方。

答案 1 :(得分:0)

我意识到这有点晚了,但以防其他人发现:

viewset.py:

class UserViewSet(RetrieveModelMixin, UpdateModelMixin, GenericViewSet):
    queryset = None
    serializer_class = serializers.UserSerializer

    def get_object(self):
        return self.request.user

这不是以上示例的完整示例,但是是一个很好的示例。这里的get_object并不依赖于查询集,但是仍然可以提供没有pk的对象。

urls.py:

urlpatterns = [
    # GET:  /user/ [Retrieve]
    # PUT:  /user/ [Update]
    url(
        r'^user/$',
        UserViewSet.as_view({'get': 'retrieve', 'put': 'update'}),
        name='user'
    ),
]

此处,路由以标准Django格式定义,而不是依靠drf路由器来提供url(该URL自动包含pk对象)。这样可以删除详细信息pk(或添加可选的内容等)。