Django提供了一个高级的框架,用它只需要很少的几行代码就能完成一个Web应用。
Django中容易犯的和元组相关的错误:
>>> b = ("just-one")
>>> b[0]
'j'
>>> d = "just-one",
>>> d[0]
'just-one'
元组是由逗号决定的,而不是小括号。
Python的装饰器指的是一种让你能改变或者说“装饰”函数行为的机制,它能让函数执行一些和原本设计不同,或时在原有基础上额外的操作。装饰器也可以说是对函数的一个包装。这些额外的任务包括写日志、计时、过滤等。
@deco
def foo():
pass
在这个例子里,deco就是一个装饰了foo函数的装饰器函数(decorator function)。它先把foo函数拿过来,加上一些额外功能后再重新赋值给foo。@deco的语法和下面的代码是等价的。
foo = deco(foo)
一个简单的例子:
def log(func):
def wrappedFunc():
print "*** %s() called" % func.__name__
return func()
return wrappedFunc
@log
def foo():
print "inside foo()"
执行代码后所生成的结果:
>>> foo()
*** foo() called
inside foo()
项目是一个包含了组成单个网站的所有文件的目录。
Django提供了一个叫django-admin.py的命令来帮助创建一个项目的目录。
为blog项目创建一个项目目录的django-admin.py命令是:
django-admin.py startproject mysite
生成的目录中:
startproject命令创建的所有文件都是Python的源代码文件。这里没有XML、.ini文件,或是任何时髦的配置语法。Django追求的是尽可能地保持“纯Python”这一理念。
Django内置了一个Web服务器,它不是用来部署公共站点的,而是用来快速开发,优点如下:
启动服务器:
./manage.py runserver
有了项目之后就可以在它下面创建应用,按Django的说法是app。
创建blog app:
./manage.py startapp blog
要告诉Django这个app是项目里的一部分,需要编辑settings.py文件(配置文件)。
在settings.py文件尾部找到INSTALLED_APPS元组。把app以模块的形式添加到元组中(注意结尾的逗号):
'mysite.blog'
在models.py文件中加入以下代码:
class BlogPost(models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
timestamp = models.DateTimeField()
每个变量都和普通的类属性一样被定义为一个特定变量类(field class)的实例。这些变量类也是在django.models里定义,它们的种类非常多,从BooleanField到XMLField应有尽有。
在settings.py文件中设置数据库引擎、用户名、密码等信息,书中写的是设置DATABASE_ENGINE
、DATABASE_NAME
等变量,比如:
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = r'C:\py\django\db\django.db'
不过最新版本的Django貌似是使用以下方式:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
创建表
执行以下命令后Django会在指定数据库中创建某些表:
./manage.py syncdb
*** 本人兴高采烈地装上最新版的Django,实践发现和书中的不完全一样,比如syncdb已经不支持了,而是改成了migrate,所以这本书的笔记还是只记录基本原理吧,详细步骤就不记录了 ***
在models.py中定义的BlogPost模型类实际上相当于定义了一个表,而成员变量则是一个个字段,执行上述命令后,Django将在数据库中自动根据models.py中的定义创建一系列表。
当然在settings.py中列出的app才能自动创建出表。
通过添加admin应用,可以通过 http://127.0.0.1:8000/admin 页面来管理注册到admin应用的模型,可以往模型(数据库表)中添加记录,相当于一个数据库管理页面。
在settings.py文件中INSTALLED_APPS元组中添加'django.contrib.admin',
。
每次添加完应用都要执行更新数据库表的命令。
接下来是在admin应用中注册模型,blog/models.py中:
from django.db import models
from django.contrib import admin
class BlogPost(models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
timestamp = models.DateTimeField()
admin.site.register(BlogPost)
从Django的角度来说,一个页面具有三个典型的组件:
模板就是一个html文件,其中可以使用特殊的变量标签,用来获得传入的数据,也可以使用for循环等,可以将模板标签理解为Django定义的一种特殊的语法,就像嵌在HTML文档中的PHP脚本一样。
<h2>{{ post.title }}h2>
<p>{{ post.timestamp }}p>
<p>{{ post.body }}p>
假设传给模板一个名为post的BlogPost模型对象,以上的模板代码分别从BlogPost对象的titile、timestamp、body变量里获取了相应的值。
使用for模板标签显示多篇blog帖子:
{% for post in posts %}
<h2>{{ post.title }}h2>
<p>{{ post.timestamp }}p>
<p>{{ post.body }}p>
{% endfor %}
将以上模板代码保存到blog app目录里的templates目录下。
想在编写一个从数据库读取所有blog帖子的视图函数,并用我们的模板将它们显示出来。
打开blog/views.py然后输入:
from django.template import loader, Context
from django.http import HttpResponse
from mysite.blog.models import BlogPost
def archive(request):
posts = BlogPost.objects.all()
t = loader.get_template("archive.html")
c = Context({ 'posts' : posts })
return HttpResponse(t.render(c))
每个Django视图函数都将django.http.HttpRequest对象作为它的第一个参数。
我们的页面还差一步就可以工作了,还需要一个URL。
第一步:
在mysite/urls.py中添加url(r'^blog/', include('mysite.blog.urls'))
,此句是把blog开头的URL转到blog目录下的urls.py处理
第二步:
在blog/urls.py中添加:
from django.conf.urls.defaults import *
from mysite.blog.views import archive
urlpatterns = patterns('', url(r'^$'), archive)
以上代码是对URL使用archive视图函数进行显示。
小总结:
Django的大体流程如下:浏览器中输入URL,URL将由urls.py进行路由,交由指定的views.py中的视图函数进行显示,视图函数通过models.py从数据库中获得数数据然后将数据传入模板文件(包含模板标签的HTML文件),经过处理后,最终的HTML文件被发送到浏览器客户端。
可能多个页面会基于同一个基础风格,首先创建一个base.html,其中包含以下模板便签:
{% block content %}
{% endblock %}
然后可以定义一个子模板继承该基础模板:
{% extends "base.html" %}
{% block content %}
...
{% endblock %}
该子模板表示继承base.html,并且将子模板中的content命名块中的所有内容填入到base.html中相应的块中。
设置model的默认排序方法是给它定义一个Meta嵌套类:
class Meta:
ordering = ('-timestamp',)
如果省略掉开头的’-’,则按升序排列。
{{ post.timestamp|date }}
使用一个管道符号,就可以把过滤器应用到变量之上了。date是一个过滤器。
基本流程:用户向Web服务器请求一个文档,Web服务器随即获取或生成这个文档,服务器再把结果返回给用户的浏览器,最后浏览器将这个文档渲染出来。
Django将请求和响应表示成相对简单的Python对象,用属性来表示其数据,以及用方法来进行更复杂的操作。
SQL是用来定义和查询数据库的语言,通常被进一步抽象为一个ORM(对象关系映射),它可以把数据库里的数据映射为面向对象语言里的代码对象。
多个控制器可以根据用户的不同对同一个数据模型做出不同程度的访问,或是允许通过GUI应用以及email或是命令行来提交数据。