Django rest框架-调用另一个基于类的视图

时间:2018-07-03 01:53:51

标签: django django-rest-framework django-views

我已经仔细研究了几篇类似的文章(Calling a class-based view of an app from another app in same project似乎很有希望,但没有用),但是有些文章年龄较大,对我来说却没有什么用。这是我的设置(使用Django == 2.0.6,djangorestframework == 3.8.2)

我有一个基本模型(在这里简化):

from django.db import models
class Resource(models.Model):
    name = models.CharField(max_length=100, null=False)

我有一个基本端点,可以在其中列出和创建Resource实例:

from rest_framework import generics, permissions
from myapp.models import Resource
from myapp.serializers import ResourceSerializer

class ListAndCreateResource(generics.ListCreateAPIView):
    queryset = Resource.objects.all()
    serializer_class = ResourceSerializer
    permission_classes = (permissions.IsAuthenticated,)

(afaik,序列化程序的详细信息不相关,因此省略了。)

无论如何,除了该基本端点外,我还有另一个API端点,该端点执行一些操作,但还会在流程中创建一些Resource对象。当然,我想利用ListAndCreateResource类中封装的功能,因此我只需要维护创建Resource的位置。

我尝试过:

尝试1:

class SomeOtherView(generics.CreateAPIView):
    def post(self, request, *args, **kwargs):
        # ... some other functionality...
        # ...
        response = ListAndCreateResource().post(request, *args, **kwargs)
        # ... more functionality...
        return Response({'message': 'ok'})

不幸的是,这对我不起作用。在我的踪迹中,我得到:

  File "/home/projects/venv/lib/python3.5/site-packages/rest_framework/generics.py", line 111, in get_serializer
    kwargs['context'] = self.get_serializer_context()
  File "/home/projects/venv/lib/python3.5/site-packages/rest_framework/generics.py", line 137, in get_serializer_context
    'request': self.request,
AttributeError: 'ListAndCreateResource' object has no attribute 'request'

尝试2: 此尝试尝试使用as_view方法,该方法是所有基于Django类的视图的一部分:

class SomeOtherView(generics.CreateAPIView):
    def post(self, request, *args, **kwargs):
        # ... some other functionality...
        # ...
        response = ListAndCreateResource.as_view()(request, *args, **kwargs)
        # ... more functionality...
        return Response({'message': 'ok'})

但是这放弃了:

AssertionError: The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`

我的问题是 ...是否有直接的方法来做到这一点?我可以访问_request对象(类型为rest_framework.request.Request的{​​{1}}属性,但是然后我没有DRF {{1}中包含的任何身份验证详细信息}对象(实际上,如果我在上述尝试#2中使用django.http.HttpRequest,我的Request返回403)。

谢谢!

3 个答案:

答案 0 :(得分:3)

这似乎有点晚了,但万一有人想知道。

class SomeOtherView(generics.CreateAPIView):
    def post(self, request, *args, **kwargs):
        # ... some other functionality...
        # ...
        response = ListAndCreateResource.as_view()(request, *args, **kwargs)
        # ... more functionality...
        return Response({'message': 'ok'})

as_view()是一个函数,当被调用时,它返回一个接受请求的函数* args,** kwargs。因此,基本上,类视图是封装的函数视图。

答案 1 :(得分:0)

您可以在基于类的视图中访问requestself.request

答案 2 :(得分:0)

我认为您可以使用 request._request。 DRF 保留从 API 调用接收的受保护成员 _request。