笨鸟编程-零基础入门Pyhton教程

 找回密码
 立即注册

编写你的第一个 Django 程序 第3部分

发布者: 三寸日光



编写更多视图

现在让我们添加一些视图到 polls/views.py 中去。这些视图与之前的略有不同,因为 它们有一个参数::

def detail(request, poll_id):
    return HttpResponse("You're looking at poll %s." % poll_id)

def results(request, poll_id):
    return HttpResponse("You're looking at the results of poll %s." % poll_id)

def vote(request, poll_id):
    return HttpResponse("You're voting on poll %s." % poll_id)

将新视图按如下所示的 url() 方法添加到 polls.urls 模块中去::

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    # ex: /polls/
    url(r'^$', views.index, name='index'),
    # ex: /polls/5/
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)

在你的浏览器中访问 http://localhost:8000/polls/34/ 。将运行 detail() 方法并且显示你在 URL 中提供的任意 ID 。试着访问 http://localhost:8000/polls/34/results/ 和 http://localhost:8000/polls/34/vote/ – 将会显示对应的结果页及投票页。

当有人访问你的网站页面如 “ /polls/34/ ” 时,Django 会加载 mysite.urls 模块,这是因为 ROOT_URLCONF 设置指向它。接着在该模块中寻找名为``urlpatterns`` 的变量并依次匹配其中的正则表达式。 include() 可让我们便利地引用其他 URLconfs 。请注意 include() 中的正则表达式没有 $ (字符串结尾的匹配符 match character) 而尾部是一个反斜杠。当 Django 解析 include() 时,它截取匹配的 URL 那部分而把剩余的字符串交由 加载进来的 URLconf 作进一步处理。

include() 背后隐藏的想法是使 URLs 即插即用。 由于 polls 在自己的 URLconf(polls/urls.py) 中,因此它们可以被放置在 “/polls/” 路径下,或 “/fun_polls/” 路径下,或 “/content/polls/” 路径下,或者其他根路径,而应用仍可以运行。

以下是当用户访问 “/polls/34/” 路径时系统中将发生的事:

  • Django 将寻找 '^polls/' 的匹配

  • 接着,Django 截取匹配文本 ("polls/") 后剩余的文本 – "34/" – 传递到 ‘polls.urls’ URLconf 中作进一步处理, 再将匹配 r'^(?P<poll_id>\d+)/$' 的结果作为参数传给 detail() 视图

    detail(request=<HttpRequest object>, poll_id='34')
    

poll_id='34' 这部分就是来自 (?P<poll_id>\d+) 匹配的结果。 使用括号包围一个 正则表达式所“捕获”的文本可作为一个参数传给视图函数;?P<poll_id> 将会定义名称用于标识匹配的内容; 而 \d+ 是一个用于匹配数字序列(即一个数字)的正则表达式。

因为 URL 模式是正则表达式,所以你可以毫无限制地使用它们。但是不要加上 URL 多余的部分如 .html – 除非你想,那你可以像下面这样::

(r'^polls/latest\.html$', 'polls.views.index'),

真的,不要这样做。这很傻。

在视图中添加些实际的功能

每个视图只负责以下两件事中的一件:返回一个 HttpResponse 对象,其中包含了所请求页面的内容, 或者抛出一个异常,例如 Http404 。剩下的就由你来实现了。

你的视图可以读取数据库记录,或者不用。它可以使用一个模板系统,例如 Django 的 – 或者第三方的 Python 模板系统 – 或不用。它可以生成一个 PDF 文件,输出 XML , 即时创建 ZIP 文件, 你可以使用你想用的任何 Python 库来做你想做的任何事。

而 Django 只要求是一个 HttpResponse 或一个异常。

因为它很方便,那让我们来使用 Django 自己的数据库 API 吧, 在 教程 第1部分 中提过。修改下 index() 视图, 让它显示系统中最新发布的 5 个调查问题,以逗号分割并按发布日期排序::

from django.http import HttpResponse

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
    output = ', '.join([p.question for p in latest_poll_list])
    return HttpResponse(output)

在这就有了个问题,页面的设计是硬编码在视图中的。如果你想改变页面的外观,就必须修改这里的 Python 代码。因此,让我们使用 Django 的模板系统创建一个模板给视图用,就使页面设计从 Python 代码中 分离出来了。

首先,在 polls 目录下创建一个 templates 目录。 Django 将会在那寻找模板。

Django 的 TEMPLATE_LOADERS 配置中包含一个知道如何从各种来源导入模板的可调用的方法列表。 其中有一个默认值是 django.template.loaders.app_directories.Loader ,Django 就会在每个 INSTALLED_APPS 的 “templates” 子目录下查找模板 - 这就是 Django 知道怎么找到 polls 模板的原因,即使我们 没有修改 TEMPLATE_DIRS, 还是如同在 教程 第2部分 那样。

组织模板

我们 能够 在一个大的模板目录下一起共用我们所有的模板,而且它们会运行得很好。 但是,此模板属于 polls 应用,因此与我们在上一个教程中创建的管理模板不同, 我们要把这个模板放在应用的模板目录 (polls/templates) 下而不是项目的模板目录 (templates) 。 我们将在 可重用的应用教程 中详细讨论我们 为什么 要这样做。

在你刚才创建的``templates`` 目录下,另外创建个名为 polls 的目录,并在其中创建一个 index.html 文件。换句话说,你的模板应该是 polls/templates/polls/index.html 。由于知道如上所述的 app_directories 模板加载器是 如何运行的,你可以参考 Django 内的模板简单的作为 polls/index.html 模板。

模板命名空间

现在我们 也许 能够直接把我们的模板放在 polls/templates 目录下 ( 而不是另外创建 polls 子目录 ) , 但它实际上是一个坏注意。 Django 将会选择第一个找到的按名称匹配的模板, 如果你在 不同 应用中有相同的名称的模板,Django 将无法区分它们。 我们想要让 Django 指向正确的模板,最简单的方法是通过 命名空间 来确保是 他们的模板。也就是说,将模板放在 另一个 目录下并命名为应用本身的名称。

将以下代码添加到该模板中:

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

现在让我们在 index 视图中使用这个模板:

from django.http import HttpResponse
from django.template import Context, loader

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = Context({
        'latest_poll_list': latest_poll_list,
    })
    return HttpResponse(template.render(context))

代码将加载 

Archiver|手机版|笨鸟自学网 ( 粤ICP备20019910号 )

GMT+8, 2024-10-18 14:05 , Processed in 0.015357 second(s), 17 queries .

© 2001-2020