DRF - Base Viewset for query param validation

寵の児 提交于 2019-12-12 02:27:44

问题


I am using Django 1.9 and Django Rest Framework 3.3

I'm creating three new endpoints that are similar but still different enough that I want them to be their own viewsets to avoid messy code. They are not backed by a model so I am extending ViewSet directly. One similarity between all three endpoints is they require the same two query parameters. So I find I am doing this:

class MyFirstViewset(viewsets.ViewSet):

    def list(self, request):
        some_param = request.query_params.get('someparam')
        if not some_param:
            return Response('someparam query parameter is required', status.HTTP_400_BAD_REQUEST)
        some_other_param = request.query_params.get('someotherparam')
        if not some_other_param:
              return Response('someotherparam query parameter is required', status.HTTP_400_BAD_REQUEST)


class MySecondViewset(viewsets.ViewSet):

    def list(self, request):
        some_param = request.query_params.get('someparam')
        if not some_param:
            return Response('someparam query parameter is required', status.HTTP_400_BAD_REQUEST)
        some_other_param = request.query_params.get('someotherparam')
        if not some_other_param:
              return Response('someotherparam query parameter is required', status.HTTP_400_BAD_REQUEST)

As you can see... it's not very DRY. An obvious solution would be inheritance with a base viewset doing the similar parts of validation, the problem is I'm not sure what the best practice is for doing something like this with DRF. Would I want to make a protected access validation function and call that? But if all I was doing was checking a dict for keys it wouldn't even have to be in a ViewSet right? Just having the last class do the validation in list() then calling that in all the child viewsets also seems odd to me since then I am using list() to validate and not actually return anything in the base class.

Could anyone tell me what a good approach to this would be? What's best practice for cases like this? I Googled around but couldn't find anything. Any advice would be appreciated. Thanks!


回答1:


One reason for why Class Base class are better is exactly that you can add your own derivation or at least add MixIns, so from the pure coding point of view, I think you should just add your own MyBaseViewSet and have MyFirstViewset and MySecondViewset derive from it.

That said, consider overwriting get_queryset instead of list, and use ListAPIView so you get some default behavior, and just return an empty array or if you really want to return an error, through an exception:

class MyBaseViewSet(generics.ListAPIView):
    serializer_class = YourSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        some_param = self.request.query_params.get('someparam')
        if not some_param:
             raise exceptions.PermissionDenied


来源:https://stackoverflow.com/questions/36505792/drf-base-viewset-for-query-param-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!