Django 快速实战入门(五):数据模型
django
作者:Hily 原始链接:http://hily.me/blog/2008/11/learning-django-ch5/
版权声明:可以转载,转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
ORM 与 CRUD
在当今绝大多数的 Web 应用中,数据库已经成为不可或缺的一个重要组成部分。对于许多应用来说,使用传统的开发方法,仍然要编写不少 SQL 语句,让许多开发者感到枯燥乏味。
由此,在许多面向对象的开发模型中,引入了对象关系映射(ORM )机制,对关系数据库进行抽象与建模。引入了 ORM 之后,对数据库的操作不再是直接通过 SQL 语句,而是直接操作于数据对象。
Django 作为一个优秀的 Web 开发框架,它也实现了 ORM,支持 CRUD。在许多应用中,SQL 语句大多数都是比较简单的,因此 CRUD 基本上能满足大多数场合的应用,大大提升了开发效率。
下面我们就要使用 Django 的 ORM 机制,建立一个简单的留言板,来领略一下无 SQL 的应用开发。
配置数据库
在这部分,我们将使用 MySQL 作为留言数据的存储引擎,如果你还没安装 MySQL 和 MySQLdb,请回到第二节进行安装。
要在 Django 项目中使用数据库,我们需要修改一下项目目录下的 settings.py,这里以 MySQL 为例,修改以下数据库相关的选项:
DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', ’sqlite3' or 'oracle'.
DATABASE_NAME = 'mydb' # Or path to database file if using sqlite3.
DATABASE_USER = 'root' # Not used with sqlite3.
DATABASE_PASSWORD = 'hily' # Not used with sqlite3.
DATABASE_HOST = ” # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ” # Set to empty string for default. Not used with sqlite3.
(注意,在大多数情况下,直接把 root 作为 Web 应用的数据库用户是不安全的,这里是为了简便才这样做的。)
新建 Django 应用
在 Django 中,项目为应用提供了运行环境,一个项目中可以包含多个应用,同一个项目下的应用共享着项目的配置信息,如数据库配置、模板路径、时区等信息。一个应用以一个包的形式存在,便于重用和移植。
从第一节的 Django 架构图中我们可以看到,数据模型(Model)是存在于应用(Application)之中的,因此要使用数据模型,需要首先建立一个 Django 应用。使用以下命令:
python manage.py startapp messages
执行成功后,会在项目目录下新建一个名为 comments 的目录,这就是 comments 应用包的路径,startapp 会对它进行初始化。初始化后包含三个文件:
gentoo myblog # ls messages/
__init__.py models.py views.py
对这三个文件作一下简要说明:
__init__.py:同项目目录下的 __init__.py,表示这是一个包。
models.py:模型定义。一会儿我们就需要在这里面定义数据模型。
views.py:该应用的视图控制实现代码。
新建的应用在 Django 项目中默认是不启用的,因此我们需要修改 settings.py 来启用我们的留言板应用,同时先禁用其它暂时不用的应用:
INSTALLED_APPS = (
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.sites',
'myblog.messages',
)
在 INSTALLED_APPS 尾部加上 'myblog.messages' 即可。
新建应用后,models.py 和 views.py 都是空的,下一步我们就要对它们进行填充实现。
建立留言板模型
我们要实现的留言板由以下部分组成:
留言者
邮箱
主页
留言标题
留言内容
留言时间
留言者 IP
根据以上描述,在 models.py 中定义它:
from django.db import models
class Message(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
homepage = models.URLField()
title = models.CharField(max_length=200)
content = models.CharField(max_length=500)
time = models.DateTimeField(auto_now_add=True)
ip = models.CharField(max_length=20)
Comment 类继承自 Django 的 models.Model 类,models.CharField、models.DateTimeField 等都是 Django 数据模型中支持的类型,更多可用类型请参考官方手册。
安装模型
到这里为止,我们还没有对数据库做任何结构定义操作,在开发应用时习惯先建立数据库和表结构的朋友可能会有点儿迷惑,这些数据表什么时候会被创建?在这一步里,我们就要做这个事情,通过安装模型把模型定义同步到数据库。
首先使用以下命令验证一下模型的有效性:
python manage.py validate
如果提示“0 errors found”,则表示模型被正确定义,否则请返回修改。
在开始安装模型前,你可能需要查看一个安装模型时执行的 SQL 语句,你可以使用以下命令查看:
python manage.py sqlall messages
执行后结果类似:
gentoo myblog # python manage.py sqlall messages
BEGIN;
CREATE TABLE `messages_message` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(30) NOT NULL,
`email` varchar(75) NOT NULL,
`homepage` varchar(200) NOT NULL,
`title` varchar(200) NOT NULL,
`content` varchar(500) NOT NULL,
`time` datetime NOT NULL,
`ip` varchar(20) NOT NULL
)
;
COMMIT;
确认无误后使用以下命令将模型同步到数据库:
python manage.py syncdb
这将会在数据库中建立一个 messages_message 表。
使用数据模型
这一节中,我们暂不打算为留言板创建视图控制,这部分我们将在下一节中实现。但是我们希望先通过一些简单的方法来快速测试一下这个数据模型。
下面我们就通过使用 Python 命令行来测试这个数据模型,如果直接通过输入 python 来启动 shell,那么在导入一些 Django 相关的库时会发生错误,因为缺少相关环境变量的设置。
所以,我们需要使用以下命令启动 Python 命令行:
python manage.py shell
导入数据模型并显示所有留言:
>>> from messages.models import Message
>>> Message.objects.all()
[]
因为当前数据表中并没有存在任何留言记录,所以 Message.objects.all() 显示为空。
新增留言:
>>> m = Message(name='Hily',
… email='hily@test.com',
… homepage='http://hily.me/',
… title='My first message',
… content='This is my first message.',
… ip='192.168.1.5')
>>> m.save()
>>> Message.objects.all()
[<Message: Message object>]
要使 Message.objects.all() 输出可阅读的信息,我们需要修改 Message 类,增加 __str__ 方法:
from django.db import models
class Message(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
homepage = models.URLField()
title = models.CharField(max_length=200)
content = models.CharField(max_length=500)
time = models.DateTimeField(auto_now_add=True)
ip = models.CharField(max_length=20)
def __str__(self):
return 'Name: %s Email: %s Homepage: %s/n' /
'Time: %s IP: %s/n' /
'Title: %s/nContent: %s/n' /
% (self.name, self.email, self.homepage,
self.time, self.ip,
self.title, self.content);
重新启动 shell,查看所有留言记录:
>>> from messages.models import Message
>>> Message.objects.all()
[<Message: Name: Hily Email: hily@test.com Homepage: http://hily.me/
Time: 2008-11-21 09:00:17 IP: 192.168.1.5
Title: My first message
Content: This is my first message.
>]
更新记录:
>>> m = Message.objects.get(name='Hily')
>>> m.content = 'Is this my first message?'
>>> m.save()
>>> Message.objects.all()
[<Message: Name: Hily Email: hily@test.com Homepage: http://hily.me/
Time: 2008-11-21 09:00:17 IP: 192.168.1.5
Title: My first message
Content: Is this my first message?
>]
删除记录:
>>> m = Message.objects.get(name='Hily')
>>> m.delete()
>>> Message.objects.all()
[]
Django 的 CRUD 为大家演示到此,更多更丰富的模型操作语句,请参考官方手册。
转贴] Django 快速实战入门(六):表单模型
在与用户的交互过程中,表单发挥了十分重要的作用,多数 Web 应用都带有许多的表单处理。与数据模型类似,如果使用传统的开发方法,那么表单页面的编写和提交结果的验证和处理将成为开发者一大头疼事。
因此,Django 中将表单抽象为模型,集表单生成、内容验证为一体。通过视图控制将表单模型、数据模型结合在一起,就可以很容易地实现表单结构的设计、对用户提交数据的验证和数据的保存入库等操作。
下面我们继续上一节中的示例,为留言板创建一个表单页面。
创建表单模型
要利用 Django 的表单模型来创建一个表单页面,就需要先建立一个表单模型。我们在应用目录 messages/ 目录下新建一个表单模型文件 forms.py,专门用于存放各种表单模型:
from django import forms
class MessageForm(forms.Form):
name = forms.CharField(required=True)
email = forms.EmailField(required=True)
homepage = forms.URLField(required=False)
title = forms.CharField(required=True)
content = forms.CharField(required=True)
forms.CharField、forms.EmailField 同上一节我们使用的字段类型一样,是 Django 内置的表单类型,更多的类型和参数说明请参考官方手册。
required=True 表示这个字段是必须填写的,否则表单验证时将会提示错误。
创建留言页的视图控制
在视图控制函数中生成一个表单对象,最后交由模板系统格式化显示,同时显示留言记录。
修改后的 messages/views.py 内容如下:
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response·
from forms import MessageForm
from models import Message
def message(request):
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
homepage = form.cleaned_data['homepage']
title = form.cleaned_data['title']
content = form.cleaned_data['content']
ip = request.META['REMOTE_ADDR']
m = Message(name=name,
email=email,
homepage=homepage,
title=title,
content=content,
ip=ip)
m.save()
return HttpResponseRedirect('/message/')
else:
form = MessageForm()
messages = Message.objects.all().order_by('-time')
return render_to_response('message.html',
{'form': form, 'messages': messages})
当用户提交留言后,request.method 值为 POST,这时候我们使用 MessageForm(request.POST) 来处理表单内容。
如果验证通过,则 form.is_valid() 为 True,这时我们就把提交的内容添加到数据库中,这些提交的内容经过验证后都保存在 form.cleaned_data 字典中。
最后返回一个 HttpResponseRedirect 对象,作用是重定向到 /message/ 页,防止用户刷新导致重复提交数据。
实现页面模板
模板 templates/message.html:
<html>
<head>
<title> Leave your message here </title>
</head>
<body>
<h1>Messages</h1>
<table>
{% for message in messages %}
<tr>
<td>
{% if message.homepage %}
<a href="{{ message.homepage }}">{{ message.name }}</a>
{% else %}
{{ message.name }}
{% endif %}
({{ message.email }})
leave a message at {{ message.time }}
from {{ message.ip }}:
</td>
</tr>
<tr>
<td>{{ message.content }}</td>
</tr>
{% endfor %}
</table>
<h2>Leave your message</h2>
<form action="." method="POST">
<table>
{{ form.as_table }}
</table>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
其中 as_table 是 form 的一个属性,form.as_table 表示使用表格形式输出时要输出的 HTML 代码。
为保持应用的封装,我们可以在每个应用目录下创建一个模板目录 templates,然后把这个目录添加到项目配置文件 settings.py 中的模板搜索路径中:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('//', '/'),
os.path.join(os.path.dirname(__file__), 'messages/templates').replace('//',
'/'),
)
配置访问接口
实现好视图控制后,我们需要修改 urls.py 配置留言板访问接口,可以简单地在 patterns.py 中增加一行:
(r'^message/$', 'myblog.messages.views.message'),
如果希望应用的可移植性更好一些,我们可以为每个应用单独维护一个 urls.py,然后在项目的 urls.py 中引入。
新建 messages/urls.py,内容如下:
from django.conf.urls.defaults import *
from views import *
urlpatterns = patterns(”,
(r'^$', message),
)
然后在项目的 urls.py 中包含它:
urlpatterns = patterns(”,
(r'^$', index),
(r'^message/', include('myblog.messages.urls')),
)
这样,在访问 http://192.168.1.6:8080/message/ 时,项目中的 urls.py 会匹配 message/,并把匹配完的剩余部分传递给应用中的 urls.py,这里的剩余部分就是空字符串,因此在 messages/urls.py 中的 r'^$' 将会匹配它。
最终效果
访问 http://192.168.1.6:8080/message/,增加几笔留言,你可能会发现时间与当前时间不匹配。这时你需要根据你所在的时区修改一下 settings.py 中的时区:
TIME_ZONE = 'Asia/Shanghai'
如果输入有误,则会在输入错误的表单域上方显示错误提示,如: