我可以从另一个视图中调用一个视图吗?
Posted
技术标签:
【中文标题】我可以从另一个视图中调用一个视图吗?【英文标题】:Can I call a view from within another view? 【发布时间】:2011-06-16 01:14:46 【问题描述】:我的一个视图需要添加一个项目以及其他功能,但我已经有另一个视图专门添加一个项目。
我可以这样做吗:
def specific_add_item_view(request):
item = Item.objects.create(foo=request.bar)
def big_view(request):
# ...
specific_add_item_view(request)
【问题讨论】:
我认为它的使用更简单:return specific_add_item_view(request) 【参考方案1】:如果你这样做:
def calledView(bar):
...
return Response(...)
def base_view(request):
resp = add_stuff(request)
...
你可能会得到这个错误:
request
参数必须是django.http.HttpRequest
,不是rest_framework.request.Request
。
所以你应该这样做:
def calledView(request):
...
return Response(...)
def base_view(request):
resp = add_stuff(request._request)
...
【讨论】:
【参考方案2】:你可以这样做:
def foo(req):
# code
def index(req):
return foo(req)
【讨论】:
【参考方案3】:没有基于类的视图:
def my_view(request):
return call_another_view(request)
def call_another_view(request):
return HttpResponse( ... )
与class based views:
def my_view(request):
return CallAnotherView.as_view()(request)
class CallAnotherView(View):
...
【讨论】:
哪个应该先出现,my_view(request)
或 CallAnotherView(View)
?
Gathide 任何一个命令都可以,由你决定,哪个更清楚【参考方案4】:
更好的方法是使用模板系统。结合@Seth 和@brady 的想法:
def specific_add_item_view(request, extra_context_stuff=None):
Item.objects.create()
context_variables = # obviously want to populate this
if extra_context_stuff:
context_variables.update(extra_context_stuff)
return render(request, 'app_name/view1_template.html', context_variables)
def bigger_view(request):
extra_context_stuff = 'big_view': True
return specific_add_item_view(request, extra_context_stuff)
而您的 app_name/view1_template.html 可能包含条件模板标签
% if big_view %
<p>Extra html for the bigger view</p>
% endif %
【讨论】:
感谢@Neceros 指出最近的 django 版本弃用了render_to_response
以支持 render
。【参考方案5】:
视图函数应该将呈现的 HTML 返回给浏览器(在 HttpResponse
中)。在视图中调用视图意味着您(可能)进行两次渲染。相反,只需将“添加”分解到另一个不是视图的函数中,并让两个视图都调用它。
def add_stuff(bar):
item = Item.objects.create(foo=bar)
return item
def specific_add_item_view(request):
item = add_stuff(bar)
...
def big_view(request):
item = add_stuff(bar)
...
【讨论】:
如果被调用的视图在第三方应用中怎么办? Seth,如何在模板中调用view1的变量或如何利用view1的变量显示 在某些情况下,您希望视图调用另一个视图,例如使用视图下载文本/csv 文件或使用 AJAX 更新视图模板的一部分时(在这种情况下第二个视图不会直接从第一个视图调用,而是由视图模板 html 文件中的一些 jquery 或 js 调用)【参考方案6】:当然,只要说完了,您的视图就会返回一个 HttpResponse 对象。以下是完全有效的:
def view1(request):
# do some stuff here
return HttpResponse("some html here")
def view2(request):
return view1(request)
如果您不想从第一个视图返回 HttpResponse,那么只需将其存储到某个变量中即可忽略:
def view1(request):
# do some stuff here
return HttpResponse("some html here")
def view2(request):
response = view1(request)
# do some stuff here
return HttpResponse("some different html here")
【讨论】:
只是为了澄清你在做什么:在第二个例子中,你只是在 view1 中启动了一些逻辑,不会对响应对象做任何事情,对吧? 是的,就是这样。view1
可能对模型对象或其他对象进行操作。不过,赛斯的想法是正确的。最好从两个视图中取出通用功能并将其放入 view1
和 view2
都调用的函数中,然后它们返回各自的 HttpResponse 对象。无需生成不会使用的 HttpResponse - 特别是如果其中包含需要大量查询的模板。
@brady,如何在模板中调用view1的变量或如何利用view1的变量显示
虽然 Seth 的想法是正确的,但如果需要从第三方应用调用视图,您的解决方案就是最佳选择!
第二种模式不好。您偶尔可以从 view2 调用 view1,但如果这样做,它应该只是 return view1。关键是您将一些额外的参数传递给 view1,它通常不会从 url (extra_context、template、success_url,...) 获得。这里 view2 充当 view1 的代理视图。如果您需要 view1 的整个逻辑(否则应该使用逻辑提取),这几乎是唯一允许的模式。如果需要更改,您应该从第三个应用程序中查看并完全重写它。使用基于类的视图,您可以在这种情况下使用继承,因此更简洁。以上是关于我可以从另一个视图中调用一个视图吗?的主要内容,如果未能解决你的问题,请参考以下文章