Django - 两个视图,一页

时间:2012-05-15 20:09:58

标签: django django-views

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

我想要的: 此页面的URL引用视图。该视图调用另外两个视图(此处称为“子视图”),然后每个子视图呈现其截面并返回结果。然后主视图连接子视图的结果并返回该视图。

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

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

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

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

3 个答案:

答案 0 :(得分:17)

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

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

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

然而,也许你想要别的东西,即extendsinclude的模板。

使用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 %}

我希望有所帮助。

答案 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)

这是介绍class based views.

的最佳时机

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

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

The docs甚至包含一个基于请求参数返回JSON响应或HTML响应的好例子(这种情况)。

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