2.ORM
对象关系映射(Oject Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,自动生成sql语句,将程序中的对象自动保存到关系数据库中。优点:
- 隐藏了数据库访问的细节,简化了sql的使用,提高了开发效率
- 解耦业务逻辑层(view)和数据处理层(model),简化了开发流程,提高了系统的可移植性
- 提高了安全性
缺点:
- 执行效率低
- 对复杂sql无能为力
- 增加了学习成本
2.1 基本概念
面向对象概念 | 面向关系概念 |
---|---|
类 | 表 |
对象 | 记录(一行) |
属性 | 字段(属性、列) |
- 一个模型类对应一个表
- 每个模型类都必须继承django.db.models.Model
2.2 模型属性
模型中的属性和数据库表的字段对应,必须定义。模型的属性需要定义成类属性
#属性定义语法为:
属性 = models.字段类型(选项)
- 属性命名规则:
- 不能是python的保留关键字
- 不允许使用连续的下划线,因为连续下划线在查询中会用到
- 定义属性时需要指定字段类型
- 主键一般不用自己定义,django会自动创建自增长主键列,如果你自己定义了主键,则django不会再自动生成主键
2.2.1字段类型
字段名称 | 字段说明 | 参数 |
---|---|---|
AutoField | 一个根据实际Id自动增长的 IntegerField(通常不指定 自动生成) | |
CharField | 字符串,默认的表单样式是 TextInput | max_length=字符长度 |
TextField | 大文本字段,一般超过4000使用,默认的表单控件是Textarea | |
IntegerField | 整数 | |
DecimalField | 使用python的Decimal实例表示的十进制浮点数 | max_digits总位数;decimal_places小数位数 |
FloatField | 用Python的float实例来表示的浮点数 | |
BooleanField | true/false 字段,此字段的默认表单控制是CheckboxInput | |
NullBooleanField | 支持null、true、false三种值 | |
DateField | 使用Python的datetime.date实例表示的日期,该字段默认对应的表单控件是一个TextInput | auto_now和auto_now_add、default这三个参数不能同时共存 |
TimeField | 使用Python的datetime.time实例表示的时间 | 参数同DateField |
DateTimeField | 使用Python的datetime.datetime实例表示的日期和时间 | 参数同DateField |
ImageField | 继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image |
- auto_now: 每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
- auto_now_add: 当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
2.2.2 字段选项
适用于任何字段,可以实现字段的约束,在生成字段时通过方法的关键字参数指定。
可选参数 | 说明 |
---|---|
null | 如果True ,Django将NULL 在数据库中存储空值。默认是False 。不要在字符串字段上使用。null是数据库范畴的概念 |
blank | 如果True ,该字段允许为空。默认是False 。同null不同, 如果字段有blank=True ,则表单验证将允许输入空值。如果字段有blank=False ,则需要该字段。 |
db_column | 用于此字段的数据库列的名称。如果没有给出,Django将使用该字段的名称。 |
db_index | 如果True ,将为此字段创建数据库常规索引。 |
unique | 如果True ,该字段在整个表格中必须是唯一的。 |
primary_key | 如果True ,此字段是模型的主键。 |
default | 默认值 当前字段如果不给值则执行默认值 |
3.定义模型
我们可以在应用的models.py中定义模型:
from django.db import models
class 模型名(models.Model):
属性名 = models.字段名(字段选项/参数)
.....
class Meta: #可选,任何非字段的设置可以写到Meta中
db_table = 'user' #指定表名为uesr
-
数据库的表名等于:应用名_模型名,如果想指定表名,可以在Meta中使用db_table指定
-
如果没有指定主键,Django将自动给表创建一个自增长主键id
id = models.AutoField(primary_key=True)
下面我们定义几个模型类
from django.db import models
from django.utils import timezone
#用户类
class User(models.Model):
uid = models.AutoField(primary_key=True) #自增主键
uname = models.CharField(max_length=60)
password = models.CharField(max_length=32)
user_type = ((1,'超级管理员'),(2,'普通用户')) #用户自定义类型对应mysql的enum类型
type = models.IntegerField(default=2,choices=user_type)
regtime = models.DateTimeField(default=timezone.now) #缺省值是当前时间
ip = models.IntegerField(null=True)
login_type = ((1,'允许登录'),(2,'禁止登录')) #用户自定义类型对应mysql的enum类型
allowed = models.IntegerField(default=1,choices=login_type)
email = models.CharField(max_length=100,null=True)
memo = models.CharField(max_length=1000,null=True)
class Meta:
db_table = 'user' #表名
4.激活模型
-
创建迁移文件 (此刻表并没有创建到库中)
$ python3 manage.py makemigrations
-
执行迁移 (将模型创建到库中)
$ python3 manage.py migrate
然后在应用的migrations目录中应该生成了迁移文件
├── app
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
生成的表结构如下:
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`uname` varchar(60) NOT NULL,
`password` char(32) NOT NULL,
`type` enum('超级管理员','普通用户') DEFAULT '普通用户',
`regtime` datetime DEFAULT NULL,
`ip` int(11) DEFAULT NULL,
`allowed` enum('允许登录','禁止登录') DEFAULT '允许登录',
`email` varchar(100) DEFAULT NULL,
`memo` varchar(1000) DEFAULT NULL,
PRIMARY KEY (`uid`)
)
注意:
- 任何对字段或表的修改都需要重新迁移