【问题标题】:DRF - using view classes for custom URL design?DRF - 使用视图类进行自定义 URL 设计?
【发布时间】:2016-11-03 16:55:23
【问题描述】:

我想在 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 提供了许多基于类的视图和路由器,我想知道是否有更简洁的实现方式?

【问题讨论】:

    标签: django rest django-rest-framework


    【解决方案1】:

    我意识到这有点晚了,但万一其他人发现了这个:

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

    在这里,路由不是依靠drf 路由器来提供url(自动包含pk 对象),而是以标准的Django 格式定义的。这允许删除细节pk(或添加一个可选的等)。

    【讨论】:

      【解决方案2】:

      基本上,您可以创建一个视图子类 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. [用户列表]:覆盖UserListView 中的get_queryset,并提供您的逻辑来过滤用户并返回查询集。
      2. [获取用户详细信息]:同上,但覆盖UserDetailView中的get_queryset
      3. [补丁用户]:覆盖UserDetailView 中的partial_update 以提供更新逻辑。

      总之,mixins 是您开始在 DRF 上创建更通用的基于类的视图的好地方。

      【讨论】:

      • 嗯,谢谢,但这里的关键区别在于 URL。您期望在 url 中传递一个 PK(我认为 UserDetailView 中的 mixins 期望这个?)。我想要的 url 没有 PK - 它返回登录用户的详细信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多