以一个投票程序的实例来讲解python的django框架使用

(一)关于django

django是一个基于mvc构造的框架。但是在django中,控制器接受用户输入的部分由框架自行处理,所以 django 里更关注的是模型(model)、模板(template)和视图(views),称为 mtv模式。

ubuntu下的安装:一般都自带python的。网上教程比较多了….

dizzy@dizzy-pc:~$ python
python 2.7.3 (default, apr 20 2012, 22:44:07)
[gcc 4.6.3] on linux2
type “help”, “copyright”, “credits” or “license” for more information.
>>> import django
>>> help(django)
version = (1, 6, 4, ‘final’, 0)
#可以查看django版本等信息。

(二)第一个django的app

#环境:python2.7,django1.6,ubuntu12.04
python 及 django 安装成功之后,就可以创建django工程了

(1)教你开始写django1.6的第1个app

#先创建一个文件夹
dizzy@dizzy-pc:~$ mkdir python
dizzy@dizzy-pc:~$ cd python
#然后创建工程
dizzy@dizzy-pc:~/python$ django-admin.py startproject mysite
dizzy@dizzy-pc:~/python$ cd mysite
#然后这个工程就可以启动服务了
dizzy@dizzy-pc:~/python/mysite$ python manage.py runserver
validating models…
0 errors found
july 23, 2014 – 14:17:29
django version 1.6.4, using settings ‘mysite.settings’
starting development server at http://127.0.0.1:8000/
quit the server with control-c.
#这样,打开浏览器访问: 便可看到: it worked! 关闭服务:ctrl+c
#新创建的项目里面会有:manage.py文件,mysite文件夹
#在mysite文件夹里面会有:__init__.py,settings.py,urls.py,wsgi.py四个文件
#__init__.py是一个空文件,
#setting.py 是项目的配置文件。需要修改两个地方,这里使用默认的sqlite3数据库
language_code = ‘zh-cn’ #原:en-us
time_zone = ‘asia/shanghai’ #原:utc
#配置完之后,便可以创建数据表了
dizzy@dizzy-pc:~/python/mysite$ python manage.py syncdb
#创建是还要设置一个超级管理员,用于后台登录。
#设置完之后,开启服务,便可进入后台管理界面了:http://127.0.0.1:8000/admin/

(2)教你开始写django1.6的第1个app

#创建一个用于投票的app。
#进入mysite工程根目录,创建app
dizzy@dizzy-pc:~/python/mysite$ python manage.py startapp polls
dizzy@dizzy-pc:~/python/mysite$ ls polls
admin.py __init__.py models.py urls.py views.py
#这样。django已经生成了,app通常所需的模板文件。

下面创建两个models。poll 和 choice

dizzy@dizzy-pc:~/python/mysite$ vim polls/models.py

修改文件如下:

from django.db import models
# create your models here.
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_text = models.charfield(max_length=200)
votes = models.integerfield(default=0)
#基本创建model过程就是这样,细节还要深入研究!

然后修改工程的配置文件setting.py,在installed_app元组下面添加刚才创建的app:polls

dizzy@dizzy-pc:~/python/mysite$ vim mysite/settings.py
installed_apps = (
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘polls’,
)
#可以使用 python manage.py sql polls 查看app的建表sql
#使用 python manage.py syncdb 进行创建数据库表
dizzy@dizzy-pc:~/python/mysite$ ./manage.py sql polls
begin;
create table “polls_poll” (
“id” integer not null primary key,
“question” varchar(200) not null,
“pub_date” datetime not null
)
;
create table “polls_choice” (
“id” integer not null primary key,
“poll_id” integer not null references “polls_poll” (“id”),
“choice_text” varchar(200) not null,
“votes” integer not null
)
;
commit;
#这样就可以通过设置model让django自动创建数据库表了
要想在后台admin中管理polls。还需要修改app下面的admin.py 文件。
from django.contrib import admin
# register your models here.
from django.contrib import admin
from polls.models import choice,poll
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)
#这部分代码,大体能看懂,具体的规则还要稍后的仔细研究。
##这部分代码,由于拼写失误,导致多处出错。细节决定成败!!

这样再重启服务,就能在后台管理polls应用了。

(3)视图和控制器部分

前面已经完成了model(m)的设置。剩下的只有view(v)和urls(c)了。django的视图部分,由views.py 和 templates完成。

在polls中,我们将创建4个视图:

“index” 列表页 – 显示最新投票。
“detail” 投票页 – 显示一个投票的问题, 以及用户可用于投票的表单。
“results” 结果页 – 显示一个投票的结果。
投票处理 – 对用户提交一个投票表单后的处理。

现在修改 views.py 创建用于视图的函数。

dizzy@dizzy-pc:~/python/mysite$ vim polls/views.py

from django.shortcuts import render,get_object_or_404
# create your views here.
from django.http import httpresponse
from polls.models import poll
def index(request):
latest_poll_list = poll.objects.all().order_by(‘-pub_date’)[:5]
context = {‘latest_poll_list’:latest_poll_list}
return render(request,’polls/index.html’,context)
def detail(request,poll_id):
poll = get_object_or_404(poll,pk=poll_id)
return render(request,’polls/detail.html’,{‘poll’:poll})
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)
#涉及django的自带函数,不做深究。后面再做研究!

要想使试图能被访问,还要配置 urls.py 。mysite是整个网站的urlconf,但每个app可以有自己的urlconf,通过include的方式导入到根配置中即可。现在在polls下面新建 urls.py

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\d+)/$’,views.detail,name=’detail’),
#ex:/polls/5/results/
url(r’^(?p\d+)/results/$’,views.results,name=’results’),
#ex:/polls/5/vote/
url(r’^(?p\d+)/vote/$’,views.vote,name=’vote’),
)
#url中,三个参数。正则的url,处理的函数,以及名称
#正则表达式!!!!!

然后在根 urls.py 文件中,include这个文件即可。

dizzy@dizzy-pc:~/python/mysite$ vim mysite/urls.py

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns(”,
# examples:
# url(r’^$’, ‘mysite.views.home’, name=’home’),
# url(r’^blog/’, include(‘blog.urls’)),
url(r’^polls/’, include(‘polls.urls’,namespace=”polls”)),
url(r’^admin/’, include(admin.site.urls)),
)
#有example:两种形式。因为是元组,所以开始有“ ‘’, ”。

然后开始创建模板文件。在polls下,创建templates文件夹。下面有index.html, detail.html 两个文件。

{% if latest_poll_list %}

{% for poll in latest_poll_list %}
{{ poll.question }}
{% endfor %}

{% else %}

no polls are available.

{% endif %}
{{ poll.question }}

{% for choice in poll.choice_set.all %}
{{ choice.choice_text }}
{% endfor %}

(4)投票功能完善

上面只是简单的实现了视图功能,并没有真正的实现投票功能。接下来就是完善功能。

#修改模板文件
dizzy@dizzy-pc:~/python/mysite$ vim polls/templates/polls/detail.html
#需要加入form表单
{{ poll.question }}
{% if error_message %}

{{ error_message }}

{% endif %}

{% csrf_token %}
{% for choice in poll.choice_set.all %}

{{ choice.choice_text }}
{% endfor %}

然后需要修改 views.py 中的 vote 处理函数。进行post数据的接收与处理。

# 文件 polls/views.py
from django.shortcuts import get_object_or_404, render
from django.http import httpresponseredirect, httpresponse
from django.core.urlresolvers import reverse
from 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(request, ‘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(‘polls:results’, args=(p.id,)))

在投票成功之后,让用户浏览器重定向到结果 results.html 页。

def results(request, poll_id):
poll = get_object_or_404(poll, pk=poll_id)
return render(request, ‘polls/results.html’, {‘poll’: poll})

然后就需要创建模板 results.html 。

{{ poll.question }}

{% for choice in poll.choice_set.all %}
{{ choice.choice_text }} — {{ choice.votes }} vote{{ choice.votes|pluralize }}
{% endfor %}

vote again?

至此,重启服务就能看到单选按钮,以及submit了。