六、模型层(ORM)
Django中内嵌了ORM框架,不需要直接编写SQL语句进行数据库操作,而是通过定义模型类,操作模型类来完成对数据库中表的增删改查和创建等操作。
O是object,也就类对象的意思。
R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思。
M是mapping,是映射的意思。
映射:
类:sql语句table表
类成员变量:table表中的字段、类型和约束
类对象:sql表的表记录
ORM的优点
- 数据模型类都在一个地方定义,更容易更新和维护,也利于重用代码。
- ORM 有现成的工具,很多功能都可以自动完成,比如数据消除、预处理、事务等等。
- 它迫使你使用 MVC 架构,ORM 就是天然的 Model,最终使代码更清晰。
- 基于 ORM 的业务代码比较简单,代码量少,语义性好,容易理解。
- 新手对于复杂业务容易写出性能不佳的 SQL,有了ORM不必编写复杂的SQL语句, 只需要通过操作模型对象即可同步修改数据表中的数据.
- 开发中应用ORM将来如果要切换数据库.只需要切换ORM底层对接数据库的驱动【修改配置文件的连接地址即可】
ORM 也有缺点
- ORM 库不是轻量级工具,需要花很多精力学习和设置,甚至不同的框架,会存在不同操作的ORM。
- 对于复杂的业务查询,ORM表达起来比原生的SQL要更加困难和复杂。
- ORM操作数据库的性能要比使用原生的SQL差。
- ORM 抽象掉了数据库层,开发者无法了解底层的数据库操作,也无法定制一些特殊的 SQL。【自己使用pymysql另外操作即可,用了ORM并不表示当前项目不能使用别的数据库操作工具了。】
我们可以通过以下步骤来使用django的数据库操作
1. 配置数据库连接信息 2. 在models.py中定义模型类 3. 生成数据库迁移文件并执行迁文件[注意:数据迁移是一个独立的功能,这个功能在其他web框架未必和ORM一块的] 4. 通过模型类对象提供的方法或属性完成数据表的增删改查操作
讯享网
6.1、配置数据库连接
在settings.py中保存了数据库的连接配置信息,Django默认初始配置使用sqlite数据库。

- 使用MySQL数据库首先需要安装驱动程序
讯享网pip install pymysql
2.在Django的工程同名子目录的__init__.py文件中添加如下语句
from pymysql import install_as_MySQLdb install_as_MySQLdb() # 让pymysql以MySQLDB的运行模式和Django的ORM对接运行
作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。
3.修改DATABASES配置信息settings.py
讯享网DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', # 数据库主机 'PORT': 3306, # 数据库端口 'USER': 'root', # 数据库用户名 'PASSWORD': '', # 数据库用户密码 'NAME': 'student' # 数据库名字 } }
4.在MySQL中创建数据库
create database student; # mysql8.0默认就是utf8mb4; create database student default charset=utf8mb4; # mysql8.0之前的版本
5.注意3: 如果想打印orm转换过程中的sql,需要在settings中进行如下配置:
讯享网LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
6.2、定义模型类
定义模型类
- 模型类被定义在"子应用/models.py"文件中。
- 模型类必须直接或者间接继承自django.db.models.Model类。
接下来以学生管理为例进行演示。[系统大概3-4表,学生信息,课程信息,老师信息],创建子应用student,注册子应用并引入子应用路由.
settings.py,代码:
INSTALLED_APPS = [ # ... 'student', ]
urls.py,总路由代码:
讯享网urlpatterns = [ # 省略,如果前面有重复的路由,改动以下。 path("student/", include("student.urls")), ]
在models.py 文件中定义模型类。
from django.db import models from datetime import datetime # 模型类必须要直接或者间接继承于 models.Model class BaseModel(models.Model): """公共模型[公共方法和公共字段]""" # created_time = models.IntegerField(default=0, verbose_name="创建时间") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # auto_now_add 当数据添加时设置当前时间为默认值 # auto_now= 当数据添加/更新时, 设置当前时间为默认值 updated_time = models.DateTimeField(auto_now=True) class Meta(object): abstract = True # 设置当前模型为抽象模型, 当系统运行时, 不会认为这是一个数据表对应的模型. class Student(BaseModel): """Student模型类""" #1. 字段[数据库表字段对应] SEX_CHOICES = ( (0,"女"), (1,"男"), (2,"保密"), ) # 字段名 = models.数据类型(约束选项1,约束选项2, verbose_name="注释") # SQL: id bigint primary_key auto_increment not null comment="主键", # id = models.AutoField(primary_key=True, null=False, verbose_name="主键") # django会自动在创建数据表的时候生成id主键/还设置了一个调用别名 pk # SQL: name varchar(20) not null comment="姓名" # SQL: key(name), name = models.CharField(max_length=20, db_index=True, verbose_name="姓名" ) # SQL: age smallint not null comment="年龄" age = models.SmallIntegerField(verbose_name="年龄") # SQL: sex tinyint not null comment="性别" # sex = models.BooleanField(verbose_name="性别") sex = models.SmallIntegerField(choices=SEX_CHOICES, default=2) # SQL: class varchar(5) not null comment="班级" # SQL: key(class) classmate = models.CharField(db_column="class", max_length=5, db_index=True, verbose_name="班级") # SQL: description longtext default "" not null comment="个性签名" description = models.TextField(default="", verbose_name="个性签名") #2. 数据表结构信息 class Meta: db_table = 'tb_student' # 指明数据库表名,如果没有指定表明,则默认为子应用目录名_模型名称,例如: users_student verbose_name = '学生信息表' # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 #3. 自定义数据库操作方法 def __str__(self): """定义每个数据对象的显示信息""" return "<User %s>" % self.name
(1) 数据库表名
模型类如果未指明表名db_table,Django默认以 小写app应用名_小写模型类名 为数据库表名。
可通过db_table 指明数据库表名。
(2) 关于主键
django会为表创建自动增长的主键列,每个模型只能有一个主键列。
如果使用选项设置某个字段的约束属性为主键列(primary_key)后,django不会再创建自动增长的主键列。
讯享网class Student(models.Model): # django会自动在创建数据表的时候生成id主键/还设置了一个调用别名 pk id = models.AutoField(primary_key=True, null=False, verbose_name="主键") # 设置主键
默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。
(3) 属性命名限制
- 不能是python的保留关键字。
- 不允许使用连续的2个下划线,这是由django的查询方式决定的。__ 是关键字来的,不能使用!!!
- 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名 = models.字段类型(约束选项, verbose_name="注释")
(4)字段类型
| 类型 | 说明 |
|---|---|
| AutoField | 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性 |
| BooleanField | 布尔字段,值为True或False |
| NullBooleanField | 支持Null、True、False三种值 |
| CharField | 字符串,参数max_length表示最大字符个数,对应mysql中的varchar |
| TextField | 大文本字段,一般大段文本(超过4000个字符)才使用。 |
| IntegerField | 整数 |
| DecimalField | 十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数,常用于表示分数和价格 Decimal(max_digits=7, decimal_places=2) ==> 99999.99~ 0.00 |
| FloatField | 浮点数 |
| DateField | 日期参数auto_now表示每次保存对象时,自动设置该字段为当前时间。参数auto_now_add表示当对象第一次被创建时自动设置当前。参数auto_now_add和auto_now是相互排斥的,一起使用会发生错误。 |
| TimeField | 时间,参数同DateField |
| DateTimeField | 日期时间,参数同DateField |
| FileField | 上传文件字段,django在文件字段中内置了文件上传保存类, django可以通过模型的字段存储自动保存上传文件, 但是, 在数据库中本质上保存的仅仅是文件在项目中的存储路径!! |
| ImageField | 继承于FileField,对上传的内容进行校验,确保是有效的图片 |

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/56249.html