Django REST框架-根据请求提供常规网页和API响应的视图

Edg*_*yan 2 django django-rest-framework

我正在使用Django REST框架编写网站。这是我使用REST的第一天,所以请多多包涵。基本上,问题是

  1. 我是否可以提出一个基于类的视图,该视图既可以用作Android开发人员的API(具有JSON响应),又可以用作呈现常规Django模板的视图?或者我必须为此定义两个不同的视图?
  2. 如果问题1的答案是我必须定义两个单独的视图,那么考虑到查询集是相同的,最干的方法是什么?

风景:

class TestList(APIView):
        renderer_classes = [TemplateHTMLRenderer]
        template_name = 'android/test.html'

        def get(self, request):
            queryset = Test.objects.all()
            return Response({'test_qs': queryset})
Run Code Online (Sandbox Code Playgroud)

换句话说,假设我有一个模型查询集,我既想将其在我的网站上呈现给最终用户,又要发送给我的Android开发人员。就REST框架代码架构而言,最佳实践是什么?两种不同的基于类的视图?还是一个视图里面有两种方法?还是用一种魔术方法就能为我做两件事的一种观点?

opa*_*ski 5

我建议将其分开。使用简单的CRUD-您不会遇到DRY的问题,因为它们只是不同的视图,请考虑:

DRF(基本上,所有这些都用于CRUD,如果您只想使用列表:ListModelMixin):

class ServiceViewSet(viewsets.ModelViewSet):
    queryset = Service.objects.all()
    serializer_class = ServiceSerializer
Run Code Online (Sandbox Code Playgroud)

我认为将其合并到一个视图中-迟早会给您带来麻烦。

什么样的麻烦?

  • 与REST API相比,模板在某些时候可以使用更多数据向用户显示页面(简单示例:当前时间)-您将开始为模板实现不同的上下文,为REST实现不同的上下文;
  • 没想到;)但是我感觉到两种不同的观点使其更加清晰。

我也了解重复两次相同代码的风险-但您始终可以将重复代码提取到某些帮助结构中。

至于queryset(如果很简单),不要费心在一个地方存储它。如果它变得复杂-再次-将查询集存储在某种帮助结构中并在两个视图中使用都没有问题:

class ProjectQuerysets(object):
    my_test_qs = Test.objects.filter(created_at__gte=now-timedelta(seconds=30)).all()
Run Code Online (Sandbox Code Playgroud)

或者更复杂的事情:

class TestQSMixni(object):

    def get_queryset(self, *args, **kwargs):
         return Test.objects.filter(user=self.request.user)  # something like that;
Run Code Online (Sandbox Code Playgroud)

然后:

class TestList(TestQSMixin, APIView):

    def get(self, *args, **kwargs):
        queryset = self.get_queryset()

# and in REST:

class ServiceViewSet(TestQSMixin, viewsets.ModelViewSet):
    serializer_class = ServicesSerializer
    # no queryset needed here
Run Code Online (Sandbox Code Playgroud)

(例如,对此服务很抱歉,但是我在一些注释中有此内容:))

希望这会对您有所帮助。

最后-一切都取决于您的需求:)和项目要求。

快乐的编码。