Django 之 ORM
简介
定义
Django 框架自带的ORM 系统(python 还有其他ORM 模块如: SQLAlchemy )
特点
1 配置简单 2 开发迅速 3 性能低于pysql
ORM 定义
对象关系映射(Object Relational Mapping,简称ORM)
说明
是将面向对象语言程序中的对象自动持久化到关系数据库中 (sql 语句转化 ODD(面向对象))
转化中有性能损耗
本质是一个中间件
基本使用
1 配置
1 导包
------settings----
# django 配置项
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'download', #数据库名字
'USER': 'root', #账号
'PASSWORD': 'mysql', #密码
'HOST': '127.0.0.1', #IP
'PORT': '3306', #端口
"OPTIONS": {"init_command": "SET default_storage_engine=INNODB;"}
}
}
# 应用配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',]
-----model.py----
# 导入基类文件
from django.db import models
models.Model
2 创建模型(类)
# demo
class VerifyCode(models.Model): # 创建模型类 对应数据库表
# 定义类属性 对应表字段
code = models.CharField("兑换码", max_length=50, help_text="兑换码")
# 字段类型
# CharField 对应char
# DateTimeField 对应DateTime
add_time = models.DateTimeField("添加时间", default=datetime.now, help_text="添加时间")
is_true = models.BooleanField("是否使用", default=False, help_text="是否使用")
class Meta:
# Meta子类 可以定义一些有关数据库或者数据表的相关信息,这些相关信息我们称之为元数据
verbose_name = "兑换码"
verbose_name_plural = verbose_name
def __str__(self):
# "返回一个对象的描述信息
return self.code
3 迁移文件(关联数据库)
命令
python manage makemigrations
python manage migrate
# 已有数据库逆向成模型
python manage.py inspectdb
python manage.py inspectdb > app/models.py
Django模型属性和MySQL数据库数据类型对应关系
分类 | 模型属性类型 | sql数据类型 |
---|---|---|
自增 | AutoField | int |
布尔 | BooleanField | tinyint |
NullBooleanField | tinyint | |
字符 | CharField | varchar |
EmailField | varchar | |
TextField | longtext | |
数字 | IntegerField | int |
DecimalField | decimal | |
FloatField | double | |
日期和时间 | DateField | date |
TimeField | time | |
DateTimeField | datetime | |
文件 | FileField | varchar |
ImageField | varchar | |
外键 | ForeignKey | alter table B add constraint A_B_Ids foreign key(Aid) references A(Ids) |
ManytoMany | 建中间表再关联外键 |
2 使用模型
数据库操作(CURD)
# 新增数据
model_obj = VerifyCode()
model_obj["code"] = "123"
model_obj.save()
# 查询操作
model_obj1 = VerifyCode.objects.filter("code"="123")[0]
# 更新操作
model_obj1["code"] = "234"
model_obj1.save()
# 删除操作
model_obj1.delete()
# 还有其他方式这是用的比较多的
使用技巧
更多使用
批量上传
insert_list = []
for i range(n):
obj = OrderModel(a=1,b=2, ..)
insert_list.append(obj)
OrderModel.objects.bulk_create(insert_list)
# bulk_create 有个小问题,当其中有一个数据错误的时候错误数据都会上传失败,优点是上传速度很快比正常快很多倍
级联操作
定义一张表上某字段的存在依赖于其他表或本表的字段
强关联:(外键关联)
定义: 在数据库层进行了强关联 数据有主从关系 ,修改主键从可能建受影响,且是自动发生的
主键:不用操作
从键:设置外键关联主键
弱关联 :(逻辑关联)
只在逻辑层进行数据关联,修改主键只能手动去改从建
外键使用
一,一对多使用(ForeignKey)
# 案例
# 建立外键
class User(models.Model):
name = models.AutoField("id", help_text="id") # 一般默认会有这个可以不写
name = models.CharField("名字", max_length=50, help_text="名字")
class VerifyCode(models.Model):
code = models.CharField("兑换码", max_length=50, help_text="兑换码")
user=models.ForeignKey(User, to_field="id",related_name='SalesSite_Order', null=True, on_delete=models.CASCADE,help_text='用户')
"""
on_delete设置
CASCADE 删除级联,当父表的记录删除时,子表中与其相关联的记录也会删除
PROTECT 子表记录所关联的父表记录被删除时,会报ProtectedError异常
SET_NULL 子表记录所关联的父表记录被删除时,将子表记录中的关联字段设为NULL,注意:需要允许数据表的该字段为NULL。
SET_DEFAULT 子表记录所关联的父表记录被删除时,将子表记录中的关联字段设为一个给定的默认值。
DO_NOTHING 子表记录所关联的父表记录被删除时,什么也不做。
"""
# 使用外键
user_obj = User(name="reno")
user_obj.save()
code_obj = VerifyCode(code="123",user_obj)
# 当删除主键时
user_obj.delete()
# 如果 on_delete=models.CASCADE 从键对应数据自动改变
# 查询
user_obj = code_obj.user # 得到主键对象
code_query = user_obj.code_obj # 得到从键集合
二,多对多使用(ManytoMany)
多对多 情况会有不同,相当于两个键是互相依赖的没有主从概念,数据层的体现是会另外建一个中间表存储二者的关系,删除其中一方另一方没有影响,不过中间表对应部分删除,外键建在任意一边都可以
# 案例
# 建立外键
class User(models.Model):
name = models.AutoField("id", help_text="id") # 一般默认会有这个可以不写
name = models.CharField("名字", max_length=50, help_text="名字")
class VerifyCode(models.Model):
code = models.CharField("兑换码", max_length=50, help_text="兑换码")
user=models.ManyToMany(User, through="UserVerifyCode") # through 建立中间表模型
class UserVerifyCode(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE)
VerifyCode=models.ForeignKey(User, on_delete=models.CASCADE)
# 创建
user_obj = User(name="reno")
code_obj = VerifyCode(code="123")
user_code_obj = UserVerifyCode(user_obj, code_obj)
# 查
code_query = user_obj.VerifyCode_set.all()
user_query = code_obj.User.all()