假设我们有一个显示项目列表的Django页面,并允许用户填写表单以添加到项目中(让我们调用项目帖子)。
我想要的: 此页面的URL引用视图。该视图调用另外两个视图(此处称为“子视图”),然后每个子视图呈现其截面并返回结果。然后主视图连接子视图的结果并返回该视图。
理想情况下,我会在页面上进行快速javascript检查 - 如果启用了javascript,表单的提交按钮将“Ajax'd”到处理表单添加的子视图,页面将是以这种方式更新。我想我之后可能会触发一个刷新帖子列表的请求。
那么如何在主视图中连接两个子视图?这可能吗?
更新:“子视图”是我编写的术语。我想要的是一个视图,可以通过Ajax直接调用以返回有意义的内容,或者从另一个视图(我将其称为“主视图”)调用。如果被这个“主视图”调用,主视图如何处理从多个“子视图”返回数据?
有一种简单的方法吗?这是一种适当的方式来考虑页面中的多个视图吗?我应该关心职责分离吗?
答案 0 :(得分:17)
视图应仅包含与视图相关的逻辑:
外包计算以使其可重复使用,并从您的视图中调用这些方法以使其保持较小。
然而,也许你想要别的东西,即extends
和include
的模板。
使用extends
,您可以为HTML代码创建基本布局,并定义可在其他位置呈现的特定块。例?确定。
base.html文件:
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
<div id="header">
<h1>My Site</h1>
</div>
{% block content %}{% endblock %}
</body>
</html>
然后,在任何其他模板中,您可以覆盖我们在基本模板中定义的块title
和content
:
{% extends "base.html" %}
{% block title %}My Page{% endblock %}
{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
{% endblock %}
此外,您可以创建如下所示的子模板,我们将其命名为_item.html
:
<li class="item">
<span>{{ something.foo }}</span>
<strong>{{ something.bar }}</span>
</li>
您可以将该代码段包含在任何其他模板中,并传递任意数量的参数:
{% for something in mymodel.mym2mrelation.all %}
{% include "_item.html" with something=something only %}
{% endfor %}
当然,您可以结合这两个概念。像这样:
{% extends "base.html" %}
{% block title %}My Page{% endblock %}
{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
<ul>
{% for something in mymodel.mym2mrelation.all %}
{% include "_item.html" with something=something only %}
{% endfor %}
</ul>
{% endblock %}
我希望有所帮助。
答案 1 :(得分:15)
django中的视图只是最终返回Response对象的任何可调用对象。在该视图中,您可以将工作分成适合您的任何组织。也许你的观点100%委托给其他方法。
在您的情况下,您的主视图将调用其他2个函数来获取数据。如果它们也接受Request对象并使用它,它们也可以是视图。他们还需要返回Response对象才能被视为django视图,因为这是您将URL指向它们的方式。但是让其他两个视图返回Response对象并不是一件好事。你可能想要的只是执行特定任务并返回一些数据结构的其他方法,或者甚至是模板的渲染片段。然后,您将使用这些数据,或将模板字符串合并在一起并在主响应中返回。
如果你真的开始使用其他返回Response对象的视图,那么你可以做一些事情,比如抓住它们的主体,然后将它们合并到你自己的响应中:
https://docs.djangoproject.com/en/1.4/ref/request-response/
真的,没有什么与教程有很大不同。您只是在调用其他数据方法。如果要使其有条理,则应将数据处理逻辑与视图功能分开。您的主视图会将这些数据处理函数称为值。而你的“子视图”只是简单的视图,它们也调用这些单独的数据函数并将它们包装成响应。
伪:
def mainView(request):
val = data1()
val2 = data2()
response = # val + va2 + other stuff
return response
def subView1(request):
val = data1()
response = # val + stuff
return response
def subView2(request):
val2 = data2()
response = # val2 + stuff
return response
def data1():
val = # get data
return val
def data2():
val2 = # get data
return val2
答案 2 :(得分:8)
类方法本质上是“子视图”,将逻辑拆分为可重用的片段。
如果你想要拆分函数的可读性 - 只有使用django基于类的视图(通过默认提供的所有功能以及通过类实例访问请求,kwargs,args等),它才会变得更好。 / p>
The docs甚至包含一个基于请求参数返回JSON响应或HTML响应的好例子(这种情况)。
最好的部分?您可以在将来的视图中将基于类的视图重用为mixin。查看docs示例,了解如何转换任何基于类的视图,以通过简单的子类处理模板上下文的JSON响应。