Django实战(2):创建第一个模型类
从模型开始开发似乎是个好主意。一方面模型是整个应用的核心,实现了应用的业务数据和对业务数据进行操作的约束,而视图和模板只是向用户提供操作和展现这些数据的界面;另一方面模型相对于系统的其他部分更加稳定,将模型先确定下来有助于系统其他部分的实现。DDD(领域驱动设计)更进一步将模型中的核心对象抽取出来作为“领域模型”。
从Depot应用来看,产品(Product) 应该是模型中的核心对象之一。就让我们先来实现Product模型。
创建app
我们可以从《Django第一步》中实现的工程开始。在继续之前,还要进行一些准备工作。
Django约定必须要创建app才能使用模型。这也是Django的哲学之一:
Django认为一个project包含很多个Django appl;project提供配置文件,比如数据库连接信息、 安装的app清单、模板路径等等;而一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在。
app可以在多个project之间很容易的复用。比如Django自带的注释系统和自动管理界面。
所以我们在原有工程的基础上还需要创建一个app。现在假设我们只需要一个app,并将其命名为depotapp。创建应用的脚本也是使用project目录下的managy.py:
$python manage.py startapp depotapp
就会在工程目录下创建一个depotapp目录:
depotapp/
__init__.py
models.py
tests.py
views.py
用python代码定义数据库
在《Django的第一印象》中介绍过,Django的设计是 以Python类的形式定义数据模型。之所以没有采用rails的运行时自动获取数据库schema的”魔术方式“,是出于以下的考虑:
1. 效率。运行时扫描数据库可能会带来性能问题。
2. 明确性。只通过Model类就完全知道数据库中有哪些字段,而不需要再切换到migration或schema文件中去查看,更不需要去查看数据库结构。
3. 一致性。你看到的只是Python代码,完全不需要将大脑切换到”数据库模式“,能极大提高开发效率。
4. 版本控制。rails中的数据库结构版本保存在一个个的migration文件中,这简直就是版本管理的”反模式“。Django的方式是管理Model代码文件的版本。
5. 可扩展性。可以定义数据库中不存在的”字段类型“。比如Email,URL,等等。
当然,Django也提供从现有数据库表中自动扫描生成模型的工具。
so,《Agile Web Development with Rails》中的做法是先创建数据库表:
drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
primary key (id)
);
然后再生成scaffold(包括model,controller,test,4个views等等)。
而Django的做法是,编写下面的Model类:
depot/depotapp/models.py:
from django.db import models
class Product(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
image_url = models.CharField(max_length=200)
price = models.DecimalField(max_digits=8,decimal_places=2)
如同其他的ORM,ID字段是默认声明的,不需要单独处理.
部署模型
Django 中的每一件事情都需要明确声明,也就是说,没有你的允许,Django不会主动去碰你的代码。所以我们还需要在project中进行一些配置工作才能让app生效。
不过这样的配置只需要做一次。
首先要创建数据库并配置整个project的数据库连接,为了简单起见,使用sqlite数据库。
在工程文件夹下创建db文件夹和sqlite数据库文件:
$mkdir db
$cd db
$sqlite3 development.sqlite3
然后修改配置文件settings.py, 将DATABASES改为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db/development.sqlite3',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
}
}
就完成了数据库的配置。
还需要配置project让depotapp生效,还是在settings.py中,将INSTALLED_APPS改为:
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',
'depot.depotapp',
)
接下来就可以使用模型了。先验证一下:
$python manage.py validate
0 errors found
然后可以看一下这个Model将会生成什么样的数据库:
$ python manage.py sqlall depotapp
BEGIN;
CREATE TABLE "depotapp_product" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(100) NOT NULL,
"description" text NOT NULL,
"image_url" varchar(200) NOT NULL,
"price" decimal NOT NULL
)
;
COMMIT;
最后,将模型导入数据库:
$ python manage.py syncdb
Creating tables ...
Creating table depotapp_product
Installing custom SQL ...
Installing indexes ...
No fixtures found.
至此,完成了第一个模型类的创建。