如何以编程方式在另一个视图中调用 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/urllib2 和 json 库应该可以解决您的问题(如 this answer 中所述)。
要获取 URL,您可以使用 request.get_absolute_uri() 和/或 request.get_host() 和 django.core.urlresolvers 的组合.reverse.
【讨论】:
以上是关于如何以编程方式在另一个视图中调用 Django Rest Framework 视图?的主要内容,如果未能解决你的问题,请参考以下文章
iOS9:在另一个以编程方式添加的视图中居中以编程方式添加的视图
以编程方式开始在另一个表格视图单元格中编辑 UITextField