如何以编程方式在另一个视图中调用 Django Rest Framework 视图?

Posted

技术标签:

【中文标题】如何以编程方式在另一个视图中调用 Django Rest Framework 视图?【英文标题】:How to programmatically call a Django Rest Framework view within another view? 【发布时间】:2015-01-03 15:20:11 【问题描述】:

我有以下使用 Django Rest 框架 (DRF) 构建的基于通用类的视图

class ExampleDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Example.objects.all()
    serializer_class = ExampleSerializer
    renderer_classes = (JSONRenderer, TemplatehtmlRenderer)

    def get(self, request, *args, **kwargs):

        response = self.retrieve(request, *args, **kwargs)
        if request.accepted_renderer.format == 'html':
            form = ExampleForm(data=response.data)
            return Response('data': response.data, 'form': form, template_name='example.html')

        return response

此视图允许我通过指定 format=json 或 html 从同一端点获取 JSON 数据或 HTML 表单。

我想以编程方式调用该视图以从另一个视图中获取呈现的 HTML 表单,以便将此表单包含在另一个页面中,该页面将包含更多内容。

【问题讨论】:

【参考方案1】:

我在文档中找到了解决方案...https://docs.djangoproject.com/en/1.7/topics/class-based-views/mixins/

提示来自他们的示例:

class AuthorDetail(View):

    def get(self, request, *args, **kwargs):
        view = AuthorDisplay.as_view()
        return view(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        view = AuthorInterest.as_view()
        return view(request, *args, **kwargs)

【讨论】:

不起作用。我得到The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`. 这两个项目当然有可能在对待事物的方式上存在分歧......我有一段时间没玩这个了。 看起来有人(格雷格布朗)提出了一个编辑建议,这些电话应该是return view(request._request, *args, **kwargs) - 也许这是“更新”的方式,@waqasgard......我认为值得一试。保持原样,因为它与链接的文档匹配并且对旧版本的 Django 有效。 这里是 4.0 文档的链接:docs.djangoproject.com/en/4.0/topics/class-based-views/mixins/… 它有同样的例子。【参考方案2】:
html_from_view = ExampleDetail.as_view('get': 'list')(request).content

html_from_view = ExampleDetail.as_view('get': 'retrieve')(request, pk=my_id).render().content

【讨论】:

请求是什么? ,如果我在一个 ipython shell 中 @Sérgio 阅读问题。 request 与传递给原始视图函数/get 方法的相同。如果您在 ipython shell 中,则必须使用另一种方法。例如,您可以使用 django 测试客户端模拟 http 请求。 docs.djangoproject.com/en/2.0/topics/testing/tools/… 以上方法现在可以工作,5 年后,除了使用 request._request 而不是 request 此解决方案适用于 ViewSet,但不适用于 APIView。下面由 JD Solanki 提供的解决方案适用于 APIView。【参考方案3】:

从 Django 2.2 和 DRF 3.9.2 开始,我可以使用以下代码获得响应。

response = UserItemsApiView.as_view()(request=request._request).data

上面的例子解决了以下问题:

request 参数必须是 django.http.HttpRequest 的实例,而不是 rest_framework.request.Request 使用data 属性而不是content 为我提供了该视图的结果。

【讨论】:

我得到 "b'"detail":"CSRF Failed: CSRF token missing or wrong."'" 尝试这个时,知道为什么吗?【参考方案4】:

如果我理解正确,您需要从视图 B 中获取结果,而在视图 A 中。

使用 requests/urllib2json 库应该可以解决您的问题(如 this answer 中所述)。

要获取 URL,您可以使用 request.get_absolute_uri() 和/或 request.get_host()django.core.urlresolvers 的组合.reverse.

【讨论】:

以上是关于如何以编程方式在另一个视图中调用 Django Rest Framework 视图?的主要内容,如果未能解决你的问题,请参考以下文章

iOS9:在另一个以编程方式添加的视图中居中以编程方式添加的视图

以编程方式开始在另一个表格视图单元格中编辑 UITextField

Objective-C 以编程方式在另一个视图控制器上显示视图控制器

如何以编程方式在 Django 中创建数据库视图?

以编程方式使用 Django 的 loaddata

在另一个应用视图中导入 django 应用视图