Django教程:第一个Django应用程序(3)

2013-10-08 磁针石

#承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319

#博客:http://blog.csdn.net/oychw

#版权所有,转载刊登请来函联系

# 深圳测试自动化python项目接单群113938272深圳广州软件测试开发 6089740

#深圳湖南人业务户外群 66250781武冈洞口城步新宁乡情群49494279

#参考资料:https://docs.djangoproject.com/en/1.5/intro/tutorial01/

# http://django-chinese-docs.readthedocs.org/en/latest/intro/tutorial01.html

#本文的图片没有上传,完整的文档参见:python模块笔记:http://t.cn/z8ggk71

本节关注创建公共界面 –视图(views)。

哲学

在 Django 应用中,视图是一“类”具有特定功能和模板的网页。 例如,在博客应用中,你可能会有以下视图:

§  博客首页 – 显示最新发表的博客。

§  博客详细页面 – 单个博客的固定连接。

§  基于年份的归档页 – 显示指定年份所有月份的博客。

§  基于月份的归档页 – 显示指定月份所有日期的博客。

§  基于日期的归档页 –显示指定日期所有博客。

§  评论 – 为指定博客处理评论。

在我们的投票应用中,将有以下四个视图:

§  Poll“index” 页 – 显示最新投票。

§  Poll“detail” 页 – 显示投票,无投票结果,但是可以投票。

§  Poll“results” 页 – 显示指定的投票结果。

§  投票 – 处理投票。

在 Django 中,网页及其他内容是由视图展现。视图就是简单的 Python 函数(或方法)。Django 会通过检查URL(确切地说是域名之后的那部分 URL)来匹配一个视图。

URL 模式是URL的通用形式- 比如: /newsarchive/<year>/<month>/.

Django 通过‘URLconfs’把URL 模式 (正则表达式)映射到视图。本教程中介绍URLconfs 的基本指令,更多信息参见django.core.urlresolvers

第一个视图

编辑polls/views.py:

from django.http importHttpResponse

defindex(request):

returnHttpResponse("Hello, world. You're at the poll index.")

然后配置URLconf 。在 polls 目录下创建一个名为 urls.py 的 URLconf 文档。

from django.conf.urls importpatterns,url

from polls importviews

urlpatterns=patterns('',

url(r'^$',views.index,name='index')

)

配置 mysite/urls.py 调用polls.urls:

fromdjango.conf.urls import patterns, include, url

fromdjango.contrib import admin

admin.autodiscover()

urlpatterns= patterns('',

url(r'^polls/', include('polls.urls')),

url(r'^admin/', include(admin.site.urls)),

)

启动开发服务器:python manage.py runserver 192.168.4.13:8000。访问:http://192.168.4.13:8000/polls/,将可以看到:Hello, world.You're at the poll index。

现在你在 URLconf 中配置了 index 视图。通过浏览器访问 http://localhost:8000/polls/ ,如同你在 index 视图中定义的一样,你将看到“Hello, world. You’re at the poll index.” 文字。

url() 两个必选参数: regex 和view, 两个可选参数:kwargs和name。

regex是regularexpression 的简写,这是字符串模式匹配的语法,在 Django 中就是url 模式。 Django 将请求的URL 从上至下依次匹配列表中的正则表达式,直到匹配为止。

注意这些正则表达式不会匹配 GET 和 POST 参数以及域名。 例如:针对请求http://www.example.com/myapp/,URLconf 将只查找 myapp/。而在http://www.example.com/myapp/?page=3 也是如此。

当 Django 匹配了正则表达式就会调用响应的view函数, HttpRequest作为第一个参数和正则表达式 “捕获” 值的作为其他参数。 如果是简单正则捕获,将按顺序位置传参数;如果是命名正则捕获,将按关键字传参数值。

kwargs任意关键字参数,可传一个字典至目标视图。

Name:给你的URL取名,让你在 其他地方尤其是模板中可以更方便地引用它,特别是在模板中。 这一强大的功能可允许你通过一个文件就可修改项目中的全局URL 模式。

更多视图

现在我们再增加一些有参数的视图:

defdetail(request, poll_id):

return HttpResponse("You're looking atpoll %s." % poll_id)

defresults(request, poll_id):

return HttpResponse("You're looking atthe results of poll %s." % poll_id)

defvote(request, poll_id):

return HttpResponse("You're voting onpoll %s." % poll_id)

添加对应的url映射:

fromdjango.conf.urls import patterns, url

frompolls 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://192.168.4.13:8000/polls/34/ 。将运行detail()方法并显示URL 中提供的ID 。/polls/34/results和/polls/34/vote/也有类似显示。

访问网站页面时,比如/polls/34/时,Django 会加载mysite.urls模块(settings中的ROOT_URLCONF = 'mysite.urls'),然后找到urlpatterns变量并依次匹配正则表达式。include()表示导入其他 URL配置。include()中的正则表达式没有$(字符串结尾的匹配符),尾部是一个反斜杠。当 Django 解析include()时,它截取匹配部分而把剩余的字符串交由子URLconf 作进一步处理。这样include()使 URLs 即插即用。

当用户访问 “/polls/34/”:

§  Django 匹配'^polls/'

§  Django 截取匹配文本polls/,发送34/ 到‘polls.urls’ URLconf ,后者匹配r'^(?P<poll_id>\d+)/$' 导致如下调用

detail(request=<HttpRequestobject>, poll_id='34')

添加些实际的功能

每个视图返回一个包含请求页面的内容HttpResponse对象或者抛出一个异常,例如 Http404

视图可以选择是否读取数据库记录,是否使用Django或python第三方模板系统。视图可以生成PDF 文件,输出 XML ,创建 ZIP 文件等。可以使用任何 Python 库。

下面index视图显示系统中最新发布的 5 个调查问卷,以逗号分割并按发布日期排序::

fromdjango.http import HttpResponse

from polls.modelsimport Poll

def index(request):

latest_poll_list = Poll.objects.order_by('-pub_date')[:5]

output = ','.join([p.question for p in latest_poll_list])

returnHttpResponse(output)

通过模板可以分离python和设计。

在polls目录下创建templates目录。Django 将会在那寻找模板。

Django 的TEMPLATE_LOADERS配置中查找模板的方法。 django.template.loaders.app_directories.Loader 就会在INSTALLED_APPS的templates子目录下查找模板。

在你刚创建的templates目录下,创建polls(防止不同应用有重名的模板)的目录,并在其中创建文件index.html。你的模板位于polls/templates/polls/index.html 。简写为polls/index.html就可。

{% iflatest_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 视图中使用这个模板:

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

代码将加载 polls/index.html 模板并传递 context。context是一个映射模板变量为Python 对象的字典。

在你的浏览器中加载 “/polls/” 页,你应该看到一个列表,包含了在教程 第1部分 中创建的 “What’sup” 调查。而链接指向 poll 的具体页面。

上述加载模板过程很常用,为此Django提供了快捷方式:render(),用于加载模板,填充上下文并返回一个含有模板渲染结果的HttpResponse对象。

  1. from django.shortcuts import render
  1.  
  1. from polls.models import Poll
  1.  
  1. def index(request):
  1.     latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
  1.     context = {'latest_poll_list': latest_poll_list}
  1.     return render(request, 'polls/index.html', context)

render() 函数中第一个参数是 request 对象,第二个参数是一个模板名称,第三个是一个字典类型的可选参数。它将返回根据给定模板和上下文渲染的HttpResponse对象。

抛出 404 异常

显示具体投票的视图detail:

  1. from django.http import Http404
  1. # ...
  1. def detail(request, poll_id):
  1.     try:
  1.         poll = Poll.objects.get(pk=poll_id)
  1.     except Poll.DoesNotExist:
  1.         raise Http404
  1.     return render(request, 'polls/detail.html', {'poll': poll})

poll 的 ID 不存在,视图将抛出Http404异常。我们稍后讨论如何设置polls/detail.html模板,若是你想快速运行上面的例子,在模板文件中添加如下代码:

  1. {{ poll }}

同样这也有个快捷方式。

  1. from django.shortcuts import render, get_object_or_404
  1. # ...
  1. def detail(request, poll_id):
  1.     poll = get_object_or_404(Poll, pk=poll_id)
  1.     return render(request, 'polls/detail.html', {'poll': poll})

get_object_or_404()使用Django 模型作为第一个参数,还有一些任意数量的传递到模型管理器的get()的关键字参数,若对象不存在时就抛出Http404异常。

为什么不在更高层自动捕获 ObjectDoesNotExist异常, 或者由模型 API 抛出 Http404异常?

因为那样会使模型层与视图层耦合在一起。保持松耦合Django 最重要的设计目标之一。一些耦合控制在 django.shortcuts 模块中介绍。

get_list_or_404()get_object_or_404()类似– 不过执行的是 filter() 而不是 get() 。若返回的是空列表将抛出 Http404 异常。

编写404 ( 页面未找到 ) 视图

Django 载入特定的视图来处理 404 错误,根据你的 root URLconf (仅root URLconf)中设置的handler404变量来查找视图。

一般不需要编写 404 视图。若没有设置handler404,默认使用内置的django.views.defaults.page_not_found()视图。或者在你的模板目录根目录

编写一个 500 ( 服务器错误 ) 视图

类似的,你可以在 root URLconf 中定义 handler500 变量,在服务器发生错误时调用对应的视图。视图代码产生的运行时错误会发生服务器错误。

同样,在模板根目录下创建一个500.html模板并且添加些像“出错了”之类的内容。

使用模板系统

修改polls/detail.html :

  1. <h1>{{ poll.question }}</h1>
  1. <ul>
  1. {% for choice in poll.choice_set.all %}
  1.     <li>{{ choice.choice_text }}</li>
  1. {% endfor %}
  1. </ul>

模板系统使用了“变量.属性”的语法访问变量的属性值。 例如 {{ poll.question }} , 首先 Django 对 poll 对象做字典查询。 失败之后尝试属性查询 – 在本例中属性查询成功了。 如果属性查询失败将尝试列表索引查询。

{% for %}循环中有方法调用: poll.choice_set.all即Python 代码poll.choice_set.all(),它将返回一组可迭代的Choice对象。

更多模板的信息参见 templateguide 。

移除模板中硬编码的 URLS

polls/index.html中,polls/{{ poll.id }}等是硬编码:

  1. <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>

可以在 url 配置中使用 {% url %} 模板标记来移除特定的 URL 路径依赖:

  1. <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>

其原理就是在 polls.urls 模块中寻找指定的URL 定义。 你知道命名为 ‘detail’ 的 URL 就如下所示那样定义的一样::

  1. ...
  1. # 'name' 的值由 {% url %} 模板标记来引用
  1. url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
  1. ...

如果你想将 polls 的 detail 视图的 URL 改成polls/specifics/12,那不需要在模板(或者模板集)中修改而只要在 polls/urls.py 修改:

  1. ...
  1. # 新增 'specifics'
  1. url(r'^specifics/(?P<poll_id>\d+)/$', views.detail, name='detail'),
  1. ...

URL命名空间:

如果多个应用都有名字为 detail的 视图,需要在 root URLconf 配置中添加命名空间。修改mysite/urls.py文件:

  1. from django.conf.urls import patterns, include, url
  1.  
  1. from django.contrib import admin
  1. admin.autodiscover()
  1.  
  1. urlpatterns = patterns('',
  1.     url(r'^polls/', include('polls.urls', namespace="polls")),
  1.     url(r'^admin/', include(admin.site.urls)),
  1. )

修改polls/index.htm从:

  1. <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>

为包含命名空间的 detail 视图:

  1. <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>

Django教程:第一个Django应用程序(3)的更多相关文章

  1. [大数据从入门到放弃系列教程]第一个spark分析程序

    [大数据从入门到放弃系列教程]第一个spark分析程序 原文链接:http://www.cnblogs.com/blog5277/p/8580007.html 原文作者:博客园--曲高终和寡 **** ...

  2. Pycharm+Django搭建第一个Python Web程序

    1.安装django 无论是Python2.x还是Python3.x版本,都可以使用pip来安装Django.在控制台使用如下命令:pip install django 如: 2.检查dgango是否 ...

  3. python框架之Django(1)-第一个Django项目

    准备 自己写一个简单的webServer import socket # 生成socket实例对象 sk = socket.socket() # 绑定IP和端口 sk.bind(("127. ...

  4. django创建第一个django项目-2

    安装django 虚拟环境下执行命令: pip install django==1.11.11 查看是否安装成功 pip list 列表中有django说明安装成功 创建工程 命令行移动到想要创建项目 ...

  5. Django安装+创建一个Django项目

    安装 选用pycharm    在终端输入命令:pip install django 安装完成后创建项目 1.在你想创建项目的目录下输入下面的代码 2.django-admin startprojec ...

  6. 编写你的第一个 Django 程序 第1部分

    原地址:http://django-chinese-docs.readthedocs.org/en/latest/intro/tutorial01.html 让我们通过例子来学习. 在本教程中,我们将 ...

  7. 编写你的第一个Django应用

    安装 Python 作为一个 Python Web 框架,Django 需要 Python.更多细节请参见 我应该使用哪个版本的 Python 来配合 Django?. Python 包含了一个名为  ...

  8. 第一个Django应用

    Django教程:http://www.liujiangblog.com/course/django/2 第一个Django应用 该应用包括以下两个部分: 一个可以让公众用户进行投票和查看投票结果的站 ...

  9. Django教程:第一个Django应用程序(4)

    Django教程:第一个Django应用程序(4) 2013-10-09 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...

随机推荐

  1. oracle-绑定变量学习笔记(未完待续)

    --定义变量SQL> var a number; --给绑定变量赋值SQL> exec :a :=123; PL/SQL procedure successfully completed. ...

  2. Cookie技术详解

    1. Cookie的特性 属性: 1> name: Cookie的名字 2> value: Cookie的值 3> path: 可选,Cookie的存储路径,默认情况下的存储路径时访 ...

  3. Objective-C消息机制的原理

    http://desheng.me/2012/03/31/objective-c%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6%E7%9A%84%E5%8E%9F%E7%90 ...

  4. C# XML文件操作类XmlHelper

    类的完整代码: using System;using System.Collections;using System.Xml; namespace Keleyi.Com.XmlDAL{public c ...

  5. Java hashCode 和 equals()

    1 Object中定义的hashCode() public int hashCode() Returns a hash code value for the object. This method i ...

  6. Junit4_单元测试

    不多说,直接练习学习. 1.将Junit4单元测试包引入项目:项目右键——“属性”,选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Libr ...

  7. Queue学习

    Queue在Python中可以算作是一种容器,但是他和list,set,dict不一样. 1. Queue不是Python内置类型.它在Queue模块中定义. 2. 它不是iterator容器,他不能 ...

  8. spl_autoload_register()和__autoload()

    关于spl_autoload_register()和__autoload() 看两者的用法: //__autoload用法 function __autoload($classname) {     ...

  9. PHPCMS(2)PHPCMS V9 环境搭建(转)

    转自:http://www.cnblogs.com/Braveliu/p/5072920.html PHPCMS V9的学习总结分为以下几点: [1]PHPCMS 简介 PHP原始为Personal ...

  10. linux 日常命令(磁盘空间)

    df –hl 在windows下可以很方便的查看磁盘空间的.但是到了Linux查看磁盘空间,你可能就有点摸不着头脑了,呵呵.不要急,我这就要给你解决这个问题. Df命令是Linux查看磁盘空间系统以磁 ...