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


Posted in Python onFebruary 18, 2016

(一)关于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<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$ 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 两个文件。

<!-- index.html -->
{% if latest_poll_list %}
  <ul>
  {% for poll in latest_poll_list %}
    <li><a href="{% url 'polls:detail' poll_id=poll.id %}">{{ poll.question }}</a></li>
  {% endfor %}
  </ul>
{% else %}
  <p>No polls are available.</p>
{% endif %}
 
<!--detail.html-->
<h1>{{ poll.question }}</h1>
<ul>
{% for choice in poll.choice_set.all %}
  <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
 
<!-- 视图设置完毕,具体语法还要深入研究! -->
<!-- 现在重启服务, 便可看到相应视图 -->

        (4)投票功能完善

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

#修改模板文件
dizzy@dizzy-pc:~/Python/mysite$ vim polls/templates/polls/detail.html
#需要加入form表单

<h1>{{ poll.question }}</h1>
 
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 
<form action="{% url 'polls:vote' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
  <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
  <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

            然后需要修改 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 。

<!-- polls/templates/polls/results.html -->
 
<h1>{{ poll.question }}</h1>
 
<ul>
{% for choice in poll.choice_set.all %}
  <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
 
<a href="{% url 'polls:detail' poll.id %}">Vote again?</a>

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

Python 相关文章推荐
python网络编程之TCP通信实例和socketserver框架使用例子
Apr 25 Python
python实现简单点对点(p2p)聊天
Sep 13 Python
Python批量更改文件名的实现方法
Oct 29 Python
Python中asyncio与aiohttp入门教程
Oct 16 Python
Pycharm更换python解释器的方法
Oct 29 Python
python执行精确的小数计算方法
Jan 21 Python
OpenCV+Python识别车牌和字符分割的实现
Jan 31 Python
使用Python操作FTP实现上传和下载的方法
Apr 01 Python
python3 批量获取对应端口服务的实例
Jul 25 Python
python将三维数组展开成二维数组的实现
Nov 30 Python
Python 如何操作 SQLite 数据库
Aug 17 Python
pyqt5打包成exe可执行文件的方法
May 14 Python
使用Python生成随机密码的示例分享
Feb 18 #Python
使用Python的urllib2模块处理url和图片的技巧两则
Feb 18 #Python
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
Feb 18 #Python
使用Python的PIL模块来进行图片对比
Feb 18 #Python
使用Python来编写HTTP服务器的超级指南
Feb 18 #Python
python装饰器与递归算法详解
Feb 18 #Python
Python利用Nagios增加微信报警通知的功能
Feb 18 #Python
You might like
php中二维数组排序问题方法详解
2015/08/28 PHP
很全的显示阴历(农历)日期的js代码
2009/01/01 Javascript
页面中js执行顺序
2009/11/09 Javascript
jQuery 表单验证扩展(四)
2010/10/20 Javascript
javascript 保存文件到本地实现方法
2012/11/29 Javascript
网页右键ie不支持event.preventDefault和event.returnValue (需要加window)
2013/02/22 Javascript
Javascript中匿名函数的多种调用方式总结
2013/12/06 Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
2014/11/23 Javascript
JavaScript中用于生成随机数的Math.random()方法
2015/06/15 Javascript
jquery实现全屏滚动
2015/12/28 Javascript
基于jQuery倒计时插件实现团购秒杀效果
2016/05/13 Javascript
JavaScript DOM 对象深入了解
2016/07/20 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
2016/12/07 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
element UI upload组件上传附件格式限制方法
2018/09/04 Javascript
写gulp遇到的ES6问题详解
2018/12/03 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
微信小程序实现上传word、txt、Excel、PPT等文件功能
2019/05/23 Javascript
javascript数组的定义及操作实例
2019/11/10 Javascript
react 不用插件实现数字滚动的效果示例
2020/04/14 Javascript
使用Python将数组的元素导出到变量中(unpacking)
2016/10/27 Python
python requests 测试代理ip是否生效
2018/07/25 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
2020/02/10 Python
python re模块匹配贪婪和非贪婪模式详解
2020/02/11 Python
解决python执行较大excel文件openpyxl慢问题
2020/05/15 Python
Python pymysql模块安装并操作过程解析
2020/10/13 Python
鞋子女王塔玛拉·梅隆同名奢侈品牌:Tamara Mellon
2017/11/22 全球购物
ZWILLING双立人英国网上商店:德国刀具锅具厨具品牌
2018/05/15 全球购物
澳大利亚鞋仓库:Shoe Warehouse
2019/07/25 全球购物
互联网创业计划书写作技巧攻略
2014/03/23 职场文书
五分钟演讲稿
2014/04/30 职场文书
消防标语大全
2014/06/07 职场文书
企业财务经理岗位职责
2015/04/08 职场文书
读《瓦尔登湖》有感:每个人都需要一个瓦尔登湖
2019/10/17 职场文书
详解如何使用Node.js实现热重载页面
2021/05/06 Javascript
解决MySQL添加新用户-ERROR 1045 (28000)的问题
2022/03/03 MySQL