以一个投票程序的实例来讲解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了。