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

时间:2016-12-12 19:36:44

标签: django django-rest-framework

我正在使用Django REST框架编写一个网站。这是我使用REST的第一天,所以请耐心等待。基本上,问题是,

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

    class TestList(APIView):
            renderer_classes = [TemplateHTMLRenderer]
            template_name = 'android/test.html'
    
            def get(self, request):
                queryset = Test.objects.all()
                return Response({'test_qs': queryset})
    

    换句话说,假设我有一个模型查询集,我想在我的网站上将其呈现给我的最终用户,并将其发送给我的Android开发人员。 REST框架代码体系结构方面的最佳实践是什么?两种不同的阶级观点?或者一个视图里面有两种方法呢?或者用一种魔术方法的一个视图可以为我做两个工作?

1 个答案:

答案 0 :(得分:4)

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

DRF(基本上这是CRUD的全部,如果你只想使用一个列表:ListModelMixin):

class ServiceViewSet(viewsets.ModelViewSet):
    queryset = Service.objects.all()
    serializer_class = ServiceSerializer

我认为将此合并为一个视图 - 迟早会让你陷入困境。

什么样的麻烦?

  • 您的模板在某些时候可以使用更多数据向用户显示页面而不是REST API(简单示例:当前时间) - 您将开始为模板实现不同的上下文,并为REST实现不同的上下文;
  • 并没有出现在我的脑海里;)但我觉得两个不同的观点使它更加干净。

我也理解两次重复相同代码的风险 - 但是你总是可以将重复代码提取到一些帮助结构中。

至于查询集 - 如果它很简单 - 不要打扰一个地方存储它。如果它变得复杂 - 再次 - 在一些帮助结构中存储查询集并在两个视图中使用都没有问题:

class ProjectQuerysets(object):
    my_test_qs = Test.objects.filter(created_at__gte=now-timedelta(seconds=30)).all()

或更复杂的事件:

class TestQSMixni(object):

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

后来:

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

(对不起,例如这项服务,但我在一些说明中有这个:))

希望这会对你有所帮助。

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

快乐的编码。