Chinaunix首页 | 论坛 | 博客
  • 博客访问: 259344
  • 博文数量: 33
  • 博客积分: 861
  • 博客等级: 军士长
  • 技术积分: 325
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-26 09:35
文章存档

2013年(1)

2012年(8)

2011年(25)

分类: 系统运维

2011-02-26 10:09:03

从示例学习。
开始之前,请确保 Django 已经安装完毕。先运行 Python,若正常,再输入 import django。如果运行无误,则说明 Django 已成功安装。
$ python
Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> 新建项目(Project) 你可以将你的 project 放置在任何目录下,从终端中,用 cd 命令进入理想的目录,然后运行命令,django-admin.py startproject mysite,这将创建一个名为 mysite 的项目,在其文件夹中,还自动生成了 4 个文件: • • • • init.py manage.py settings.py urls.py 这些文件的作用是:
init.py: 这是一个空文件,指示这个目录是 Python 的一个 package。
manage.py: 一个命令行工具,可以用来对 Django 项目进行各种操作。
settings.py: Django 项目的设置文件。
urls.py: Django 项目 URL 声明文件;网站的 "目录"。
运行本地服务器 Django 本身包含一个用纯 Python 语言编写的轻量级服务器,便于快速开发你的项目,而不用花费过多精力设置服务器,比如 Apache,除非你准备好正式发布网站。在 mysite 目录中,如果你紧跟着教程到此,可以直接运行命令
python manage.py runserver,启动服务器。你可以看到屏幕出现:
Validating models... 0 errors found. Django version 1.0, using settings 'mysite.settings' Development server is running at Quit the server with CONTROL-C.
此文字说明 Django 服务器已启动,可以用浏览器访问 ,如果一切正常, 你将会看到 Django 的起始页。It worked!
设置数据库接下来,编辑 settings.py 文件。
这个文件是一个普通的 Python 模块,包含模块级别的变量来规定 Django 设置。现在我们修改关于数据库的设置连接参数,去吻合你将使用的数据库。 • • • • • DATABASE_ENGINE -- 数据库引擎,常见的有:"postgresql_psycopg2"、"mysql" 或 "sqlite3"。还可选择 "postgresql" 或 "oracle"。 DATABASE_NAME -- 数据库名称。若使用 SQLite3,数据库名称是数据库文件名和其保存的绝对路径。 DATABASE_USER -- SQLite3 不用修改,为空。 DATABASE_PASSWORD -- 默认为 localhost。SQLite3 不用修改。 DATABASE_HOST -- 默认为 default。SQLite3 不用修改。使用 SQLite 数据库最简单,设置 DATABASE_ENGINE 为 sqlite3. 若使用其他类型的数据库,在此应通过命令创建新的数据库。
当你编辑 settings.py 文件时,顺便注意一下文件底部 INSTALLED_APPS 设置,默认包含如下 apps: • • • • django.contrib.auth django.contrib.contenttypes django.contrib.sessions django.contrib.sites 这些是 Django 项目默认包含的应用,比如认证系统、内容类型框架、session 框架、多网站管理的应用,这些 app 独立存在,可以根据需要保留或删除,也可应用在其他项目中。每个 app 至少对应一个数据库表,我们在 mysite 目录中运行如下命令来生成数据库表: python manage.py syncdb syncdb 会搜索 INSTALLED_APPS 中的所有 app,生成必要的书库据表。你会看到提示询问是否要为认证系统创建一个超级用户,输入 yes,根据提示完成。
创建模型我们现在已经有了一个 mysite 的项目环境,接下来让我们做点事情。你在 Django 写的每个应用都包含一个 Python package,以特定规则保存在你的 Python 目录中。Django 通过一个工具来自动生成 app 应用的基本目录,所以你可以专心编写代码而不用担心如何创建目录。 • ??目(project)与应用(app) 项目可以包含多个应用,一个应用可存在于多个项目中。应用,可以是 blog 系统,公共记录数据库,或是一个简单的投票系统等等。在这个教程中,我们将在 mysite 中创建简单的投票 poll 应用。结果这个应用被绑定在项目中,也就是通过 mysite.polls 引用投票应用。在后面的教程中,我们会讨论如何包装发布这个应用。为了创建名为 polls 的应用,确定在 mysite 的目录中,输入命令:
python manage.py startapp polls
这会创建一个名为 polls 的目录包含应用基本文件,其中包括:
polls/ __init__.py models.py views.py
我们通过修改 models.py 文件,来新建两个模型:Poll 和 Choice。模型 Poll 包含问题和发布时间。模型 Choice 包含选择文本和投票数;且每个选择被指定到一个投票上。
事实上, 即新建两个 Python 类。修改 models.py 文件为如下代码所示:
from django.db import models
class Poll(models.Model):
  question = models.CharField(max_length=200)
  pub_date = models.DateTimeField('date published')
class Choice(models.Model):
  poll = models.ForeignKey(Poll)
  choice = models.CharField(max_length=200)
  votes = models.IntegerField()
注:在 Django 0.96 之前的版本中,max_length 应改为 maxlength。代码很直观。每个模型即是一个类,是 django.db.models.Model 的子类。每个模型有不同数量的类变量,每个变量对应一个数据库字段。每个字段是 Field 类的一个实例,比如,CharField 是字符字段,而 DateTimeField 是日期时间字段。这会告诉 Django 每个字段的类型。每个字段实例的名称,比如 question 和 pub_date,也将是数据库中列的名称。一些字段类需要参数。CharField,比如,就需要参数 max_length。这不仅应用在数据库表中,也是一个输入数据时验证条件。最后,ForeignKey 表示数据库表的关系。这告诉 Django 每个 Choice 对应一个 Poll。Django 支持所有普遍的数据库关系:多对一、多对多和一对一关系。激活模型这么简短的模型代码告诉 Django 很多信息。有了它,Django 可以: • • 为这个应用创建数据库表; 创建 Python 数据库操作的 API,来调用 Poll 和 Choice 对象。但是首先,我们需要告诉项目 polls 应用已被安装。 • 哲学 Django 的 app 是可插拔的:你可以将同一 app 应用在多个项目中,你也可以发布 app 为他人使用,因为 app 不必绑定至已有 Django 安装。再次编辑 settings.py 文件,在 INSTALLED_APPS 中添加 mysite.polls,如下所示:
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'mysite.polls' )
现在 Django 已经知道 mysite 包含了 polls 应用。让我们运行另一个命令:
 python manage.py sql polls
你应该会看到如下的代码(也就是 polls 对应的 SQL 语句):
BEGIN;
CREATE TABLE "polls_poll" ( "id" serial NOT NULL PRIMARY KEY, "question" varchar(200) NOT NULL, "pub_date" timestamp with time zone NOT NULL );
 CREATE TABLE "polls_choice" ( "id" serial NOT NULL PRIMARY KEY, "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), "choice" varchar(200) NOT NULL, "votes" integer NOT NULL );
COMMIT;
再次运行 syncdb 在数据库中创建模型表。
python manage.py syncdb
命令会搜索 INSTALLED_APPS 中还未加入数据库的应用,并生成对应的数据库表。屏幕应会显示:
 Creating table polls_poll
Creating table polls_choice
Installing index for polls.Choice model
写你的第一个 Django 应用 | 第二部分 • • • • • • • • 原文地址:http://docs.djangoproject.com/en/dev/intro/tutorial02/ 启用管理后台运行开发时用服务器登录管理后台添加 Poll 模型至管理界面探索管理后台自定义管理表格添加相关对象第二部分紧接第一部分,继续完成投票应用,并关注 Django 的自动化管理后台。启用管理后台 Django 管理后台默认不启用。
启用管理后台,有三个步骤:
1. 添加 django.contrib.admin 到你的 INSTALLED_APPS 设置中。
2. 运行 python manage.py syncdb 命令。因为你在 INSTALLED_APPS 中添加了新内容, 所以数据库需要更新。
3. 编辑 mystie/urls.py 文件。取消如下三行前面的 "#" 号。
from django.contrib import admin
admin.autodiscover() (r'^admin/(.*)', admin.site.root), 运行开发时用服务器现在让我们运行服务器,来探索一下管理后台界面。还记得吗?在第一部分我们说过,运行服务器我们在终端输入如下命令:
python manage.py runserver
好的,现在开启浏览器,在地址栏中输入本地域名,比如:admin/
现在你应该可以看到管理后台的登录界面: 登录管理后台现在,试着登录。你已经在教程第一部分时创建过一个超级用户,记得吗?登录后,你应该会看到如下界面:
你可以看到一些可编辑的内容,包括 Groups, Users 和 Sites。这是默认存在的 Django 核心特性。
添加 Poll 模型至管理界面还记得刚刚创建的 Poll 模型吧,这一步我们把它加入管理界面中。也就一件事要做:我们需要告诉管理后台 Poll 模型拥有管理界面。修改 mysite/polls/models.py 文件,在文件最后添加如下代码:
from mysite.polls.models import Poll
from django.contrib import admin
admin.site.register(Poll)
马上刷新管理页面,就可以看到变化,无需重启服务器,服务器会自动重新载入你的项目, 所以任何改动都会立即显示在浏览器中。
探索管理后台现在页面出现了刚刚注册的 Poll 模型,Django 知道它应该出现在管理后台首页中。点击 "Polls",就会跳转到 poll 列表的页面,也许我们还没有任何 poll,我们可以在这里新建一个 poll。我们可以看到有两个标签:Question 和 Date published。比如我们在 Question 文本框中输入 What's up?;对于 Date published,我们可以点击 Today 和 Now 来规定发布日期为当前日期和时间。
注: • • • 这个表格是根据 Poll 模型自动生成的;
模型中不同的字段类型对应了不同的 HTML 输出。这个表格中就包含 CharField 和 DateTimeField 字段。每个 DateTimeField 字段都会有 JavaScript 支持,旁边有 Today 和 Now 以及 popup 窗口方便选择日期和时间。编辑好这个 Poll 之后,点 Save and continue editing 按钮,即保存和继续编辑,你会看到右上角出现了 History 按钮,点击它可以查看这个 Poll 的修改历史记录。自定义管理表格先花几分钟感叹一下到此你并不需要编写的代码。当调用 admin.site.register(Poll) 时,Django 会让你编辑这个对象,以及猜出如何显示它。一般我们可以让 Django 自动猜出显示编辑模型的表格,如果你想控制它,可以这么做:删除 admin.site.register(Poll) 这行代码,用一下代码替代:
class PollAdmin(admin.ModelAdmin):
   fields = ['pub_date', 'question'] admin.site.register(Poll, PollAdmin)
这里的思路是:创建一个 模型管理 对象,并将其传递给 admin.site.register()
 第二个参数(每当你需要修改模型的挂历页面时)。
上面的这次修改使 Date published 字段排到 Question 字段前面。改变两个字段的显示顺序也许不是很惊奇,但是如果碰到管理表格有一堆字段,我们就可以按照直观和习惯的顺序交换字段的显示顺序。 OK,说到一堆的字段,你也许会想把这些字段分开到两个字段区域中。我们可以修改刚才的 PollAdmin 对象为:
class PollAdmin(admin.ModelAdmin):
  fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date']}), ]
fieldsets 中的小括号是 Python 语法中的 tuple(元组),这里有两个元素,第一个元素是字段区域的名称,None 表示无名称。另外,我们还可以给字段区域一个 HTML 样式,Django 提供一个 collapse 的样式让某个字段区域默认是收起合并的。这对于表格中一些字段并不常用的情况很适用。
class PollAdmin(admin.ModelAdmin):
  fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] 添加相关对象好了,我们有了 Poll 管理页面。而一个 Poll 应该有若干个 Choice,现在管理页面还没有显示 Choice。有两种方法解决:第一个注册 Choice 像之前我们注册 Poll 一样。 from mysite.polls.models import Choice admin.site.register(Choice) 现在管理页面有了 Choices,添加页面如下: 在这个表格中,Poll 被表现为一个下拉菜单,包含所有的 Poll 对象(现在我们只有一个 What's up?)。在下拉菜单的后面,有个加号图标,点击它可以添加新的 Poll。但这不是非常有效,你想如果你想添加更多的 Choice 和在今后编辑它们,这样的操作会很麻烦。最好的方法是在 Poll 页面中,直接添加编辑其 Choice ,岂不很明了? 删除 admin.site.register(Choice) 这行代码,添加 ChoiceInline 对象,并编辑 PollAdmin :
class ChoiceInline(admin.StackedInline):
  model = Choice extra = 3
class PollAdmin(admin.ModelAdmin):
  fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] admin.site.register(Poll, PollAdmin)
这段代码会告诉 Django:Choice 对象要直接在 Poll 管理页面下编辑。默认提供 3 个多余选项。重新访问 Add Poll 页面,会看到如下页面:
尝试一下。然后考虑又一个小问题,这么多 choice 的字段占居了很长的页面,可以把两个字段并排放置,只需修改刚才 ChoiceInline 的参数为: class ChoiceInline(admin.TabularInline): #... 从 StackedInline 到 TabularInline,页面布局也换成了: 写你的第一个 Django 应用 | 第三部分 • • • • • 原文地址:http://docs.djangoproject.com/en/dev/intro/tutorial03/ 哲学 Philosophy 设计你的 URL 写你的第一个 View 让你的 View 做点什么 • • • • • • 快捷: render_to_response() 404: 页面无法找到快捷: get_object_or_404() 使用 template 模板系统简化 URLconfs 分离 URLconfs 第三部分紧接第二部分,继续完成投票应用,并关注创建显示页面的 views。哲学 View 在 Django 中是页面的 type,完成一个特定的功能或有一个特定的模板。例如,在 Blog 应用中,你也许会用到如下 View: • • • • • • Blog 首页 ── 显示最新文章单篇文章页面 ── 显示单篇文章的页面以年存档的页面 ── 显示指定年份中每月发表的文章以月存档的页面 ── 显示指定月份中每天发表的文章以天存档的页面 ── 显示指定某天中发表的文章评论 动作── 处理每篇文章的评论在我们的投票应用中,我们会用的如下四个 View: 1. 2. 3. 4. Poll 存档页面 ── 显示最新投票 Poll 查看页面 ── 显示单个投票内容 Poll 结果页面 ── 显示指定投票的结果投票 动作 ── 处理每个投票的选票在 Django 中,每个 View 就是一个简单的 Python 函数。设计你的 URL 编写 View 的第一步是,设计你的 URL 结构。也就是要创建一个 Python 模块,叫 URLconf,用来使 URL 来搭配特定的 Python 代码。当用户请求网页时,系统会查阅 ROOT_URLCONF 设置,该设置包含一个 Python 点语法的字符串。Django 调入该模块,并查找模块级别的变量 urlpatterns,格式是: (regular expression, Python callback function [, optional dictionary]) Django 从第一个正则表达式开始,向下查找,若请求 URL 符合某个正则表达式,则立即执行。详细地说,如果当符合某个正则表达式时,Django 会调用 Python 回调函数,第一个参数是 HttpRequest 对象,第二个参数是正则表达式从 URL 截取的值,第三是可选参数。对于我们的例子来说,当你创建 mysite 项目时,自动设置了 ROOT_URLCONF 为:(在 settings.py 文件中) ROOT_URLCONF = 'mysite.urls' 而且还自动创建了默认的 URLconf,在 mysite/urls.py。现在修改 urls.py 文件为: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^polls/$', 'mysite.polls.views.index'), (r'^polls/(?P\d+)/$', 'mysite.polls.views.detail'), (r'^polls/(?P\d+)/results/$', 'mysite.polls.views.results'), (r'^polls/(?P\d+)/vote/$', 'mysite.polls.views.vote'), ) 这值得解释一下。当用户请求网站的页面时,比如页面 "/polls/23/",Django 由 ROOT_URLCONF 设置,加载 URLconf 模块,并查找 urlpatterns 变量,遍历正则表达式。当找到正则表达式 r'^polls/(?P\d+)/$' 就会加载 mysite.polls.views.detail,这指向的是 mysite/polls/views.py 的 detail() 函数,会传递两个参数调用 details(): detail(request=, poll_id='23') poll_id='23' 来自 (?P\d+)。在正则表达式中,小括号之间的值会传递给 View 函数;?P 定义了传递参数的名称;而 \d+ 是匹配一个序列数字。因为 URL 规则是由一系列正则表达式组成,所以没有任何限制。而且可以给 URL 添加一个累赘,比如 .php,万一你有很冷的幽默,可以这么做: (r'^polls/latest\.php$', 'mysite.polls.views.index'), 但是,请不要这么做,有点傻。请注意正则表达式并不搜寻 GET 和 POST 参数,或域名。例如,请求网页 会搜寻 /myapp/;有如,请求页面 仍会搜寻 /myapp/。如果你想学习正则表达式,可以参阅 Wikipedia 和 Python 文档(英)。最后,提及运行性能:这些正则表达式在第一次加载 URLconf 模块时编译。他们非常快。写你的第一个 View 至今,我们还没有开始写 View,只是说了一下 URLconf。现在,让我们确保 Django 在跟随 URLconf。开启 Django 服务器。 python manage.py runserver 在浏览器中访问 应该会得到一个预计的错误:View 没有找到。 ViewDoesNotExist at /polls/ Tried index in module mysite.polls.views. Error was: 'module' object has no attribute 'index' 这个错误的出现说明在 mysite/polls/views.py 文件中还没有 index() 函数。尝试 "/polls/23/", "/polls/23/results/" 和 "/polls/23/vote/",也会出现相似错误,因为你也没有相应的 View。到时候写第一个 View 了。打开文件 mysite/polls/views.py,并添加下面代码: from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the poll index.") 这是很简单的 View,只包含一个默认 index() 函数。在浏览器中重新载入 页面,你会看到 "Hello, world. You're at the poll index."。接着添加下面 detail() 函数,参数多了一个 poll_id,是一个从 URL 中捕获的数字。 def detail(request, poll_id): return HttpResponse("You're looking at poll %s." % poll_id) 现在可以访问,例如 34/,应该会出现 "You're looking at poll 34."。让你的 View 做点什么每个 View 负责做两件事情的其中一个:要么返回一个包含请求页面内容的 HttpResponse 对象;要么返回一个错误,例如 Http404。其他的由你决定。 View 可以读取数据库数据,可以使用 template 模板系统,或第三方 Python template 模板系统。它可以轻松地生成 PDF 文件,输出 XML,新建 ZIP 文件等等,使用 Python 库可以完成几乎任何你想到的事情。 Django 所需要的就是 HttpResponse 或 一个错误。好叻。让我们编写 index() 函数,即访问 "/polls/" 的默认页面。让其显示最新的 5 个投票问题。 1. 修改 index() 函数,调用 polls/index.html 模板; 2. 设置模板路径,在 settings.py 的 TEMPLATE_DIRS; 3. 创建 polls/index.html 模板。 1. 修改 index() 函数 from django.template import Context, loader from mysite.polls.models import Poll from django.http import HttpResponse def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] t = loader.get_template('polls/index.html') c = Context({ 'latest_poll_list': latest_poll_list, }) return HttpResponse(t.render(c)) 这段代码调用 "polls/index.html" 模板,并传递内容给模板。内容是一个字典(dictionary)映射模板变量名称至 Python 对象。 2. 设置模板路径打开 settings.py 文件,修改 TEMPLATE_DIRS 内容,指向模板存放的绝对路径,而不是相对路径。模板目录可以是你硬盘的任何一个 Django 可以访问的目录,但是不要把他们放在文件的根目录中,而且不要公开它们,为了安全的原因。 3. 创建模板当你设置好模板目录后,再在其中新建一个 polls 目录,再在 polls 目录中新建一个 index.html 文件。上述 index() 中的代码 loader.get_template('polls/index.html') 就调用文件 "template_directory/polls/index.html"。而 index.html 的代码如下: {% if latest_poll_list %}
    {% for poll in latest_poll_list %}
  • {{ poll.question }} {% endfor %}
{% else %}

No polls are available.

{% endif %} 现在打开 会以列表形式显示投票系统问题。快捷:render_to_reponse() 调用模板、填充内容和返回包含内容的页面是非常普遍的流程,为了简便,Django 提供了一个 render_to_response() 的简便函数。所以 index() 函数还可以重新写成: from django.shortcuts import render_to_response from mysite.polls.models import Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] return render_to_response('polls/index.html', {'latest_poll_list': latest_poll_list}) 注意到,我们不再需要导入 loader, Context 和 HttpResponse。这个 render_to_response() 函数用模板名称作为第一个参数,用字典(dictionary)作为可选的第二个参数。它返回包含结果的 HttpResponse 对象。 404 现在我们修改一下 detail() 函数,即查看某特定投票的问题。思路是:如果投票 ID 存在, 显示投票问题;若不存在,则返回 Http404 页面无法找到的错误。 from django.http import Http404 # ... def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render_to_response('polls/detail.html', {'poll': p}) 快捷:get_object_or_404() 使用 get_object_or_404() 快捷,可以修改 detail() View, from django.shortcuts import render_to_response, get_object_or_404 # ... def detail(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/detail.html', {'poll': p}) 这个 get_object_or_404() 函数用模型名称作为第一个参数,用主键数字作为另一个参数。使用模板系统现在我们更新了 detail() 函数,而模板 polls/detail.html 的代码为: {{ poll.question }}
    {% for choice in poll.choice_set.all %}
  • {{ choice.choice }} {% endfor %}
{{ poll.question }} 是指 Poll 模型的 question 属性。{% for %} 循环。。。简化 URLconf 花一些时间尝试 View 和模板系统。当你编辑 URLconf 时,也许会注意到这里有一些冗余代码: urlpatterns = patterns('', (r'^polls/$', 'mysite.polls.views.index'), (r'^polls/(?P\d+)/$', 'mysite.polls.views.detail'), (r'^polls/(?P\d+)/results/$', 'mysite.polls.views.results'), (r'^polls/(?P\d+)/vote/$', 'mysite.polls.views.vote'), ) 也就是说,mysite.polls.views 出现在每行中。因为这是一个常见的情况,我们可以将 patterns() 的第一个参数设置为重复的前缀,例如: urlpatterns = patterns('mysite.polls.views', (r'^polls/$', 'index'), (r'^polls/(?P\d+)/$', 'detail'), (r'^polls/(?P\d+)/results/$', 'results'), (r'^polls/(?P\d+)/vote/$', 'vote'), ) 分离 URLconf 既然我们在 URLconf 这里,我们应该花一些时间把我们的 Poll 应用的 URL 从我们的 Django 项目设置中分离出来。Django 应用意味着可移植 ── 也就是说,每个应用都应该以很小的改动就可以移植到另一个 Django 项目中。拷贝文件 mysite/urls.py 到 mysite/polls/urls.py。然后,修改 mysite/urls.py 文件,移除所有关于 poll 的 URL,输入一个 include(): (r'^polls/', include('mysite.polls.urls')), include(),参照另一个 URLconf。注意这个正则表达式结尾没有 $ 符号,但保留 / 斜线。当 Django 遇到匹配 URL 时,它会把截取匹配部分,把以后的部分都传递给 include 的 URLconf,做进一步处理。若用户访问 "/polls/34/",系统会: 1. Django 会找到匹配的 '^polls/' 2. 然后,再截取掉 "polls/",把剩余的部分 "34/",传递给 ‘mysite.polls.urls’ URLconf 做处理。现在我们已经分离了 URLconf,需要修改分离出的 URLconf,删除 "polls/",最终为: urlpatterns = patterns('mysite.polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), (r'^(?P\d+)/vote/$', 'vote'), ) 在 include() 和 分离 URLconf 背后的想法是让 URL 变得简单易移植。现在既然我们的写你的第一个 Django 应用 | 第四部分 • • • • 原文地址:http://docs.djangoproject.com/en/dev/intro/tutorial04/ 写一个简单的表单使用通用 View:代码越少越好待续...... 第四部分紧接第三部分。写一个简单的表单让我们修改 poll/detail.html 模板,添加一些 粗略解释: • • • 上述模板为每个投票选项显示一个 radio 按钮,而每个按钮的值 value 都对应一个选项 ID,名称 name 为 choice。这意为,当用户选择其中一个按钮并提交表单后,传递的数据为 choice=3。这是 HTML 的基本知识。我们设置表单的动作 action 为 /polls/{{ poll.id}}/vote/, 方法 method 为 POST。使用 method="post" 十分重要,因为这会提交数据值服务器端。当你建立表单并改变服务器端的数据时,使用 method="post",这不是 Django 特有的,而是 Web 开发基本知识。 forloop.counter 只是有多少次 for` 循环。现在,让我们新建一个 View 来处理提交的数据。记着在教程的第三部分,我们建立了 Poll 应用的 URLconf,并包含这行代码: (r'^(?P\d+)/vote/$', 'mysite.polls.views.vote'), 所以我们在 mysite/polls/views.py 文件中添加 vote() 函数。 from django.shortcuts import get_object_or_404, render_to_response from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from mysite.polls.models import Choice, Poll # ... def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) try: selected_choice = p.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): # Redisplay the poll voting form. return render_to_response('polls/detail.html', { 'poll': p, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes += 1 selected_choice.save() # Always return an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. return HttpResponseRedirect(reverse('mysite.polls.views.results', args=(p.id,))) 这段代码包含一些新的知识点: • request.POST 是一个可根据名称取回提交内容的对象。比如这个例子中,request.POST['choice'] 返回选被选项的 ID 值,以字符串形式传递。request.POST 的值始终是字符串。 Django 也提供 request.GET 以同样的方法提取 GET 数据 -- 但是我们在这里使用 request.POST,确保数据只能在 POST 过程中改变。 • • 如果 POST 数据不含 choice,那么 request.POST['choice'] 将会引出 KeyError。代码会检查 KeyError` 然后显示带有错误信息的投票页面。在增加 choice 计数之后,会返回 HttpResponseRedirect 对象。该对象只有一个参数,即转向页面的 URL 地址。请记住,在成功处理 POST 数据之后,一定要返回 HttpResponseRedirect。这不是只针对 Django 的,而是 Web 开发的良好规则。 • 我们用 reverse() 函数,避免返回一个生硬的 URL 地址,反而会用 View 名称和含变量的 URL 地址。比如这个例子中,使用我们的 URLconf 设置,reverse() 返回字符串: '/polls/3/results/' ... 3 是 p.id 的值。这 URL 会调用 'results' View 显示最终页面。注意, 你需要使用 View 的全称(包括前缀)。在投票成功之后,'vote()' View 会调用 'mysite.polls.views.results',而 results() 函数为: def results(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/results.html', {'poll': p}) 这有点像 detail() 的代码,唯一的不同是调用不同的模板。我们稍后会减少这种重复代码。模板 results.html 的代码如下: {{ poll.question }}
    {% for choice in poll.choice_set.all %}
  • {{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }} {% endfor %}
使用通用 View:代码越少越好在 views.py 中会发现,detail() 和 results() 非常简单,但重复。 index() 也很相似。这些 View 表达了一个 Web 开发普遍的情况:根据 URL 中的参数从数据库读取记录,加载模板和返回渲染好的模板。因为这非常普遍,所以 Django 提供了一个快捷方式,叫做 "通用 Views" 系统。首先,打开 polls/urls.py URLconf 文件,到现在为止,文件内容应大致如下: from django.conf.urls.defaults import * urlpatterns = patterns('mysite.polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), (r'^(?P\d+)/vote/$', 'vote'), ) 现要修改文件内容为如下代码: from django.conf.urls.defaults import * from mysite.polls.models import Poll info_dict = { 'queryset': Poll.objects.all(), } urlpatterns = patterns('', (r'^$', 'django.views.generic.list_detail.object_list', info_dict), (r'^(?P\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict), url(r'^(?P\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'), (r'^(?P\d+)/vote/$', 'mysite.polls.views.vote'), ) 现在我们正在使用两个通用 View:object_list() 和 object_detail()。顾名思义,完成 显示一个对象列表 和 显示某个特定对象内容。 • • • queryset object_detail() pool_resutls

阅读(5835) | 评论(0) | 转发(0) |
0

上一篇:Django模板的使用

下一篇:HTML5 canvas

给主人留下些什么吧!~~