Yhzhtk's Blog

(热爱技术,高效Code)     归档  标签  源码  关于 


Django 学习笔记

2013-08-28    Django  python 


一、Django介绍和安装

Django 是一个高效开发实用设计的Python Web框架,是一个开放源码项目,源码托管在Github。使用Django可以很快速的开发Web项目,对于一些小的应用是相当不错的选择。其核心有:

· 用于创建模型的对象关系映射
· 为最终用户设计的完美管理界面
· 一流的 URL 设计
· 设计者友好的模板语言
· 缓存系统

我学习是在Windows上,如果在Linux上类似,首先是安装,下载Django压缩包并解压,使用以下命令安装。

tar xzvf Django-1.5.2.tar.gz
cd Django-1.5.2
python 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 # 默认端口8000
	python 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 models

class 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_group
auth_group_permissions
auth_permission
auth_user
auth_user_groups
auth_user_user_permissions
django_content_type
django_session
django_site
polls_choice
polls_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.id
	1

	# 通过python直接访问数据库字段
	>>> p.question
	"What's new?"
	>>> p.pub_date
	datetime.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自带的管理系统,只需要做以下三个操作:

  1. setting.py 文件中对INSTALLED_APPS项取消注释 "django.contrib.admin"
  2. 运行 python manage.py syncdb更新数据库
  3. 编辑mysite/urls.py文件,取消以下两个注释:

from django.contrib import admin
admin.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 admin
	from polls.models import Poll, Choice

	admin.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作为第一个参数,正则匹配的其他参数(如果有的话)传给这个view
kwargs: 传递额外的参数(dict)
name: 命名URL,让你清楚的区别其他的模板,允许你全局改变url匹配

下面新建文件 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'),
	)

最后,在polls/views.py中实现方法:


	from django.http import HttpResponse
	from polls.models import Poll

	def 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="/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, loader

	def 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 render

	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)

下面是查看详细的代码:


	from django.http import Http404
	def 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_404
	def 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="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>

{% load url from future %}




Load Disqus comments, wait a moment..

©2013 首页   关于     View me on GitHub Powered by Jekyll & Bootstrap 知识共享许可协议