以一个投票程序的实例来讲解Python的Django框架使用
(一)关于Django
Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以Django里更关注的是模型(Model)、模板(Template)和视图(Views),称为MTV模式。
Ubuntu下的安装:一般都自带Python的。网上教程比较多了....
dizzy@dizzy-pc:~$python Python2.7.3(default,Apr202012,22:44:07) [GCC4.6.3]onlinux2 Type"help","copyright","credits"or"license"formoreinformation. >>>importdjango >>>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:~$mkdirPython dizzy@dizzy-pc:~$cdPython #然后创建工程 dizzy@dizzy-pc:~/Python$django-admin.pystartprojectmysite dizzy@dizzy-pc:~/Python$cdmysite #然后这个工程就可以启动服务了 dizzy@dizzy-pc:~/Python/mysite$pythonmanage.pyrunserver Validatingmodels... 0errorsfound July23,2014-14:17:29 Djangoversion1.6.4,usingsettings'mysite.settings' Startingdevelopmentserverathttp://127.0.0.1:8000/ QuittheserverwithCONTROL-C. #这样,打开浏览器访问:便可看到:ItWorked!关闭服务: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$pythonmanage.pysyncdb #创建是还要设置一个超级管理员,用于后台登录。 #设置完之后,开启服务,便可进入后台管理界面了:http://127.0.0.1:8000/admin/
(2)教你开始写Django1.6的第1个app
#创建一个用于投票的app。 #进入mysite工程根目录,创建app dizzy@dizzy-pc:~/Python/mysite$pythonmanage.pystartapppolls dizzy@dizzy-pc:~/Python/mysite$lspolls admin.py__init__.pymodels.pyurls.pyviews.py #这样。Django已经生成了,app通常所需的模板文件。
下面创建两个models。Poll和Choice
dizzy@dizzy-pc:~/Python/mysite$vimpolls/models.py
修改文件如下:
fromdjango.dbimportmodels
#Createyourmodelshere.
fromdjango.dbimportmodels
classPoll(models.Model):
question=models.CharField(max_length=200)
pub_date=models.DateTimeField('datepublished')
classChoice(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$vimmysite/settings.py
INSTALLED_APPS=(
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
)
#可以使用pythonmanage.pysqlpolls查看app的建表SQL
#使用pythonmanage.pysyncdb进行创建数据库表
dizzy@dizzy-pc:~/Python/mysite$./manage.pysqlpolls
BEGIN;
CREATETABLE"polls_poll"(
"id"integerNOTNULLPRIMARYKEY,
"question"varchar(200)NOTNULL,
"pub_date"datetimeNOTNULL
)
;
CREATETABLE"polls_choice"(
"id"integerNOTNULLPRIMARYKEY,
"poll_id"integerNOTNULLREFERENCES"polls_poll"("id"),
"choice_text"varchar(200)NOTNULL,
"votes"integerNOTNULL
)
;
COMMIT;
#这样就可以通过设置model让Django自动创建数据库表了
要想在后台admin中管理polls。还需要修改app下面的admin.py文件。
fromdjango.contribimportadmin
#Registeryourmodelshere.
fromdjango.contribimportadmin
frompolls.modelsimportChoice,Poll
classChoiceInLine(admin.StackedInline):
model=Choice
extra=3
classPollAdmin(admin.ModelAdmin):
fieldsets=[
(None,{'fields':['question']}),
('Dateinformation',{'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$vimpolls/views.py
fromdjango.shortcutsimportrender,get_object_or_404
#Createyourviewshere.
fromdjango.httpimportHttpResponse
frompolls.modelsimportPoll
defindex(request):
latest_poll_list=Poll.objects.all().order_by('-pub_date')[:5]
context={'latest_poll_list':latest_poll_list}
returnrender(request,'polls/index.html',context)
defdetail(request,poll_id):
poll=get_object_or_404(Poll,pk=poll_id)
returnrender(request,'polls/detail.html',{'poll':poll})
defresults(request,poll_id):
returnHttpResponse("you'relookingattheresultsofpoll%s."%poll_id)
defvote(request,poll_id):
returnHttpResponse("you'revotingonpoll%s."%poll_id)
#涉及Django的自带函数,不做深究。后面再做研究!
要想使试图能被访问,还要配置urls.py。mysite是整个网站的URLConf,但每个app可以有自己的URLConf,通过include的方式导入到根配置中即可。现在在polls下面新建urls.py
fromdjango.conf.urlsimportpatterns,url
frompollsimportviews
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'),
)
#url中,三个参数。正则的url,处理的函数,以及名称
#正则表达式!!!!!
然后在根urls.py文件中,include这个文件即可。
dizzy@dizzy-pc:~/Python/mysite$vimmysite/urls.py
fromdjango.conf.urlsimportpatterns,include,url
fromdjango.contribimportadmin
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两个文件。
<!--index.html-->
{%iflatest_poll_list%}
<ul>
{%forpollinlatest_poll_list%}
<li><ahref="{%url'polls:detail'poll_id=poll.id%}">{{poll.question}}</a></li>
{%endfor%}
</ul>
{%else%}
<p>Nopollsareavailable.</p>
{%endif%}
<!--detail.html-->
<h1>{{poll.question}}</h1>
<ul>
{%forchoiceinpoll.choice_set.all%}
<li>{{choice.choice_text}}</li>
{%endfor%}
</ul>
<!--视图设置完毕,具体语法还要深入研究!-->
<!--现在重启服务,便可看到相应视图-->
(4)投票功能完善
上面只是简单的实现了视图功能,并没有真正的实现投票功能。接下来就是完善功能。
#修改模板文件
dizzy@dizzy-pc:~/Python/mysite$vimpolls/templates/polls/detail.html
#需要加入form表单
<h1>{{poll.question}}</h1>
{%iferror_message%}<p><strong>{{error_message}}</strong></p>{%endif%}
<formaction="{%url'polls:vote'poll.id%}"method="post">
{%csrf_token%}
{%forchoiceinpoll.choice_set.all%}
<inputtype="radio"name="choice"id="choice{{forloop.counter}}"value="{{choice.id}}"/>
<labelfor="choice{{forloop.counter}}">{{choice.choice_text}}</label><br/>
{%endfor%}
<inputtype="submit"value="Vote"/>
</form>
然后需要修改views.py中的vote处理函数。进行post数据的接收与处理。
#文件polls/views.py
fromdjango.shortcutsimportget_object_or_404,render
fromdjango.httpimportHttpResponseRedirect,HttpResponse
fromdjango.core.urlresolversimportreverse
frompolls.modelsimportChoice,Poll
#...
defvote(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):
#Redisplaythepollvotingform.
returnrender(request,'polls/detail.html',{
'poll':p,
'error_message':"Youdidn'tselectachoice.",
})
else:
selected_choice.votes+=1
selected_choice.save()
#AlwaysreturnanHttpResponseRedirectaftersuccessfullydealing
#withPOSTdata.Thispreventsdatafrombeingpostedtwiceifa
#userhitstheBackbutton.
returnHttpResponseRedirect(reverse('polls:results',args=(p.id,)))
在投票成功之后,让用户浏览器重定向到结果results.html页。
defresults(request,poll_id):
poll=get_object_or_404(Poll,pk=poll_id)
returnrender(request,'polls/results.html',{'poll':poll})
然后就需要创建模板results.html。
<!--polls/templates/polls/results.html-->
<h1>{{poll.question}}</h1>
<ul>
{%forchoiceinpoll.choice_set.all%}
<li>{{choice.choice_text}}--{{choice.votes}}vote{{choice.votes|pluralize}}</li>
{%endfor%}
</ul>
<ahref="{%url'polls:detail'poll.id%}">Voteagain?</a>
至此,重启服务就能看到单选按钮,以及submit了。