31

假设我们有一个显示项目列表并允许用户填写表单以添加到项目的 Django 页面(我们将项目称为帖子)。

我想要什么:这个页面的 URL 是指一个视图。该视图调用另外两个视图(此处称为“子视图”),然后每个子视图呈现其部分并返回结果。然后主视图加入子视图的结果并返回。

理想情况下,我会在页面上进行快速的 javascript 检查 - 如果启用了 javascript,表单的提交按钮将对处理表单添加的子视图“Ajax'd”,并且页面将以这种方式更新. 我想我之后也可以触发刷新帖子列表的请求或其他什么。

那么如何在主视图中连接两个子视图呢?这可能吗?

更新:“子视图”是我编造的一个术语。我想要的是一个视图,它既可以由 Ajax 直接调用以返回有意义的内容,也可以从另一个视图(我将其称为“主视图”)调用。如果被这个“主视图”调用,主视图如何处理从多个“子视图”返回数据?

有没有一种简单的方法可以做到这一点?这是考虑页面中多个视图的适当方式吗?我应该关心职责分离吗?

4

3 回答 3

20

django 中的视图只是最终返回 Response 对象的任何可调用对象。在该视图中,您可以将工作拆分为适合您的任何组织。也许您的观点 100% 委托给其他方法。

在您的情况下,您的主视图将调用 2 个其他数据函数。如果它们也接受 Request 对象并使用它,它们也可以是视图。他们还需要返回 Response 对象才能被视为 django 视图,因为这就是您将 URL 指向它们的方式。但是让其他两个视图返回 Response 对象并没有什么好处。您可能想要的只是执行特定任务并返回某些数据结构的其他方法,甚至可能是模板的渲染片段。然后,您将使用这些数据,或将模板字符串合并在一起并在您的主响应中返回。

如果您真的打算使用返回 Response 对象的其他视图,那么您可以执行一些操作,例如从它们中抓取主体,并将它们合并到您自己的响应中:
https ://docs.djangoproject.com/en/1.4 /ref/请求响应/

真的,与教程没有什么不同。您只是在为数据调用其他方法。如果你想让它有条理,你应该将数据处理逻辑与视图功能分开。您的主视图会调用这些数据处理函数来获取值。您的“子视图”只是简单的视图,它们也调用这些单独的数据函数并将它们包装到响应中。

伪:

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
于 2012-05-15T20:26:46.890 回答
19

视图应仅包含与视图相关的逻辑:

  • 视图用于处理请求并提供请求的数据
  • 这包括检查用户授权/许可和处理给定的参数
  • 如果请求的数据不是微不足道的,请将代码外包到更合适的位置(您的模型或表单定义或其他自定义位置)

外包计算以使它们可重用,并从您的视图中调用这些方法以保持它们的小。

不过,也许您还想要其他东西,即带有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>

然后,在任何其他模板中,您可以覆盖我们在基本模板中定义的titlecontent

{% 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 %}

我希望这会有所帮助。

于 2012-05-15T20:43:42.857 回答
10

这是引入基于类的视图的最佳时机。

类方法本质上是将逻辑拆分为可重用片段的“子视图”。

如果您想要拆分函数的可读性 - 只有使用 django 基于类的视图(通过默认提供的所有功能以及通过类实例访问请求、kwargs、args 等)才能变得更好。

文档甚至包含一个很好的示例,用于返回基于请求参数的 JSON 响应或 HTML 响应(这个确切的情况)。

最好的部分?您可以在未来的视图中重用基于类的视图作为 mixin。查看文档示例以了解如何转换任何基于类的视图以通过简单的子类处理模板上下文的 JSON 响应。

于 2012-05-15T20:48:43.383 回答