一、Django介绍和安装
Django 是一个高效开发实用设计的Python Web框架,是一个开放源码项目,源码托管在Github。使用Django可以很快速的开发Web项目,对于一些小的应用是相当不错的选择。其核心有:
· 用于创建模型的对象关系映射· 为最终用户设计的完美管理界面· 一流的 URL 设计· 设计者友好的模板语言· 缓存系统
我学习是在Windows上,如果在Linux上类似,首先是安装,下载Django压缩包并解压,使用以下命令安装。
tar xzvf Django-1.5.2.tar.gzcd Django-1.5.2python setup.py install
安装完成之后,在命令行输入:
python -c "import django; print(django.get_version())"
如果提示当前安装的版本号则说明安装成功了。
二、创建第一个Django项目并启动运行
接下来创建一个Django项目,将当前路径移动到你想要建立项目的地方,使用命令:
python D:\Python27\Lib\site-packages\django\bin\django-admin.py startproject mysite
注意django-admin.py在你Python的安装路径下。创建好之后,使用tree /F
(Windows下)可以查看项目文件树:
mysite │ manage.py │ └─mysite settings.py urls.py wsgi.py __init__.py
这里面各种文件看名称可以大致猜出用途,具体使用,我们下面再说,先启动这个项目,进去第一层mysite文件夹,运行命令:
python manage.py runserver # 默认端口8000python manage.py runserver 8080 # 指定端口python manage.py runserver 0.0.0.0:8000 # 指定绑定的IP和端口
便启动了项目,默认端口是8000,在浏览器输入地址: http://localhost:8000/ 就可以看到 “It worked!”
,项目就运行了。
三、创建一个APP并使用Models,数据库关系对象映射
这就是最基本的创建一个Django项目的流程。下面创建一个app,也就是网站的一个应用:
python manage.py startapp polls
查看路径,发现多了一个pools文件夹和几个文件:
│ manage.py│├─mysite│ settings.py│ urls.py│ wsgi.py│ __init__.py│└─polls models.py tests.py views.py __init__.py
其中models.py是数据库的模式类,用于存储数据库数据。我们创建两个类Poll和Choice,Poll存储问题包括问题内容和发布时间,Choice存储选择,包括指示的内容和被选的次数。
polls/models.py
from django.db import modelsclass Poll(models.Model): def __unicode__(self): return self.question question = models.CharField(max_length=200) pub_date = models.DateTimeField('date published')class Choice(models.Model): def __unicode__(self): return self.choice_text poll = models.ForeignKey(Poll) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)
每个类都继承自django.db.models.Model
,其中CharField和DateTimeField等表示数据库对应的数据类型。
Django能够完成创建数据库和完成数据库访问的功能,在使用数据库之前,我们需要先安装polls应用,编辑settings.py
,设置好DATABASES
(数据库引擎和连接信息),改变INSTALLED_APPS
添加上polls:
settings.py
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs','polls')
现在运行命令根据modes创建数据库表:
python manage.py sql polls
你将看到类似以下输出:
BEGIN;CREATE TABLE `polls_poll` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `question` varchar(200) NOT NULL, `pub_date` datetime NOT NULL);CREATE TABLE `polls_choice` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `poll_id` integer NOT NULL, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL);ALTER TABLE `polls_choice` ADD CONSTRAINT `poll_id_refs_id_3aa09835` FOREIGN KEY (`poll_id`) REFERENCES `polls_poll` (`id`);COMMIT;
这就是将要创建的表SQL语句,如果你想要查看更多关于创建数据库表的信息,你可以使用以下命令:
python manage.py validate
– 检查models是否有错python manage.py sqlcustom polls
– 输出自定义的SQL信息,如果没定义则为空python manage.py sqlclear polls
– 如果你数据库存储polls信息,则输出删除语句python manage.py sqlindexes polls
– 输出创建索引的SQL语句python manage.py sqlall polls
– 输出所有要执行的SQL语句
检测以上命令之后都没有问题,就可以执行到数据库了,运行以下命令将上面创建数据库的信息同步到数据库:
python manage.py syncdb
运行中可能需要创建Django的auth系列表,直接yes,输入用户名密码即可。创建结束之后,查看数据库表:
auth_groupauth_group_permissionsauth_permissionauth_userauth_user_groupsauth_user_user_permissionsdjango_content_typedjango_sessiondjango_sitepolls_choicepolls_poll
如果需要查看数据库,可以通过Django内置的方法,用命令简易处理数据库信息,运行命令:
python manage.py shell
会进入Shell处理程序(我安装了ipython就直接进入ipython),使用shell可以很方便的处理数据库,操作示例:
>>> from polls.models import Poll, Choice# 列出所有数据库的polls对象>>> Poll.objects.all()[]# 创建一个 Poll 的对象. 对于时间,使用 timezone.now() 替代 datetime.datetime.now()>>> from django.utils import timezone>>> p = Poll(question="What's new?", pub_date=timezone.now())# 将对象保存进数据库>>> p.save()# Now it has an ID. Note that this might say "1L" instead of "1", depending# on which database you're using. That's no biggie; it just means your# database backend prefers to return integers as Python long integer# objects.>>> p.id1# 通过python直接访问数据库字段>>> p.question"What's new?">>> p.pub_datedatetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)# 改变数据库字段,然后保存>>> p.question = "What's up?">>> p.save()>>> Poll.objects.all()[<Poll: Poll object>]# 针对类设置__unicode__方法之后,输出就变成以下内容>>> Poll.objects.all()[<Poll: What's up?>]# Make sure our __unicode__() addition worked.# Django 提供丰富的查询API,可以通过关键字参数查询>>> Poll.objects.filter(id=1)[<Poll: What's up?>]>>> Poll.objects.filter(question__startswith='What')[<Poll: What's up?>]# 查询发布时间的年>>> from django.utils import timezone>>> current_year = timezone.now().year>>> Poll.objects.get(pub_date__year=current_year)<Poll: What's up?># 如果ID不存在则会抛出异常>>> Poll.objects.get(id=2)Traceback (most recent call last):...DoesNotExist: Poll matching query does not exist. Lookup parameters were {'id': 2}# Django提供一个缩写pk表示 primary-key, 如下查询等同于Poll.objects.get(id=1).>>> Poll.objects.get(pk=1)<Poll: What's up?># Django访问关系也非常简单,获取一个Poll>>> p = Poll.objects.get(pk=1)# 获取外键关联choice,默认是一个set>>> p.choice_set.all()[]# 创建三个Choice>>> p.choice_set.create(choice_text='Not much', votes=0)<Choice: Not much>>>> p.choice_set.create(choice_text='The sky', votes=0)<Choice: The sky>>>> c = p.choice_set.create(choice_text='Just hacking again', votes=0)# Choice的访问Poll>>> c.poll<Poll: What's up?># Poll获取Choice>>> p.choice_set.all()[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>>> p.choice_set.count()3# API自动查找关系,通过Choice查找父类满足指定条件的结果# 其中current_year可以事先指定>>> Choice.objects.filter(poll__pub_date__year=current_year)[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]# 删除一个Choice>>> c = p.choice_set.filter(choice_text__startswith='Just hacking')>>> c.delete()
四、系统自带的Admin管理
启用Django自带的管理系统,只需要做以下三个操作:
- setting.py 文件中对
INSTALLED_APPS
项取消注释 "django.contrib.admin"
运行 python manage.py syncdb
更新数据库编辑mysite/urls.py
文件,取消以下两个注释:from django.contrib import adminadmin.autodiscover()url(r'^admin/', include(admin.site.urls)),
运行python manage.py runserver
启动后,输入地址 http://127.0.0.1:8000/admin/即可登录管理。
登录后发现并有没有poll表和choice表,这只是系统用户的管理,要设置数据表的管理也很简单,只需要在polls下面创建一个文件admin.py
,输入以下内容:
from django.contrib import adminfrom polls.models import Poll, Choiceadmin.site.register(Poll)admin.site.register(Choice)
重新启动,就可以看到Poll和Choice的管理界面了。管理可以完成增删改查的一些列数据库操作,方便简单。
五、URL映射,建立项目框架
修改mysite/urls.py
,添加一行Url映射,则urlpatterns为:
urlpatterns = patterns('', url(r'^polls/', include('polls.urls')), url(r'^admin/', include(admin.site.urls)),)
url(r'^polls/', include('polls.urls')),
表示将所有polls开头的url地址都转发给polls.urls.py
来处理。
url(regex, view, kwargs=None, name=None, prefix='')参数:regex: 匹配URL的正则view: 传递匹配的URL到一个指定的view方法,并将HttpRequest作为第一个参数,正则匹配的其他参数(如果有的话)传给这个viewkwargs: 传递额外的参数(dict)name: 命名URL,让你清楚的区别其他的模板,允许你全局改变url匹配
下面新建文件 polls/urls.py
:
from django.conf.urls import patterns, urlfrom polls import viewsurlpatterns = 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'),)
最后,在polls/views.py
中实现方法:
from django.http import HttpResponsefrom polls.models import Polldef index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] output = ', '.join([p.question for p in latest_poll_list]) return HttpResponse(output)def detail(request, poll_id): return HttpResponse("You're looking at poll %s." % poll_id)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)
其中参数poll_id就是匹配URL正则时匹配到的poll_id,request就是请求的request。运行项目, 输入http://localhost:8000/polls/ 就可以看到列出的所有Poll信息。输入 http://localhost/polls/34/就可以查看id为34的数据(功能还未实现,URL映射已经把功能都加进去了,具体实现在对应的方法内实现即可)。
六、使用模板快速开发应用
Django支持模板,这大大提供了灵活性和开发效率。模板文件默认放在App的templates下,如polls/templates/polls/index.html
,这样调用时使用相对路径polls/index.html
。
下面示例写一个模板文件,放在polls/templates/polls/index.html
{% if latest_poll_list %} <ul> {% for poll in latest_poll_list %} <li><a href="http://yhzhtk.info/2013/08/28/"/polls/{{ poll.id }}/">{{ poll.question }}</a></li> {% endfor %} </ul>{% else %} <p>No polls are available.</p>{% endif %}
修改polls/view.py
中的index方法,import模板支持:
from django.template import RequestContext, loaderdef index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = RequestContext(request, { 'latest_poll_list': latest_poll_list, }) return HttpResponse(template.render(context))
这样就使用模板传参数的方式显示网页,同一个模板可以在多个地方复用。由于使用模板的情况非常常见,而以上方法有点繁琐,Django提供一个简便的方式使用模板django.shortcuts.render
,以上代码可修改如下:
from django.shortcuts import renderfrom polls.models import Polldef 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)
下面是查看详细的代码:
from django.http import Http404def detail(request, poll_id): try: poll = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render(request, 'polls/detail.html', {'poll': poll})
以上等同于以下简易写法:
from django.shortcuts import render, get_object_or_404def detail(request, poll_id): poll = get_object_or_404(Poll, pk=poll_id) return render(request, 'polls/detail.html', {'poll': poll})
get_object_or_404()
,使用get方法时,如果不存在对象,则抛出404异常。
系统出现404或500时,如果想指定错误页面,可以在templates文件夹下建立文件404.html、500.html,并设定DEBUG为False,也就是非调试模式,当出现指定code时,会自动显示该页面。
Django模板也很强大,现在列出部分使用情况,后续再学习:
<h1>{{ poll.question }}</h1><ul>{% for choice in poll.choice_set.all %} <li>{{ choice.choice_text }}</li>{% endfor %}</ul><li><a href="http://yhzhtk.info/2013/08/28/"{% url "'detail' poll.id %}">{{ poll.question }}</a></li>{% load url from future %}