Django框架详细介绍---模型---ORM
一、概述
ORM(Object Relational Mapping),全称:对象关系映射,简单的说就是通过创建类、实例化出对象的方法,使得类、对象、对象的属性能够和数据库中的表、记录、字段意义对应。
ORM只是一种工具,避免了开发人员在开发过程中不用反复地编写大量复杂的SQL语句,而可以专注于业务逻辑上的开发,提高开发效率,但是ORM的使用在一定程度上牺牲了程序的执行效率
二、ORM中字段类型及其相关
准备好Django工程
1.setting.py文件中修改字典DATABASES
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
# 更改连接的数据库的相关配置
DATABASES = {
'default': {
# 连接数据库的模块
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'HOST': '127.0.0.1',
'PORT': '',
'USER': 'root',
'PASSWORD': '',
}
}
2.model文件修改
每一个模型对应一个类,而且每个类必须继承django.db.models.Model,每个类中的属性对应着每张表中某一行的对应的字段,简单的说就是Django框架为开发人员提供了自动生成的数据库访问的接口,将复杂的SQL语句编写过程转换成实例化对象和访问对象中的属性的简单方法
ORM DB
类 数据表
对象 表中某行
属性 某个字段
示例:
表结构

对应的模型
from django.db import models # Create your models here.
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
address = models.CharField(max_length=128)
create_time = models.CharField(max_length=64)
解释说明:
表Publisher的名称是自动生成的,如果要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时
id字段是自动添加的,如果要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现已经明确地设置了Field.primary_key,它将不会添加自动ID列
本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句
3.字段类型
常用字段
AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列 IntegerField
一个整数类型,范围在 -2147483648 to 2147483647 CharField
字符类型,必须提供max_length参数, max_length表示字符长度 DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例 DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
字段集合
AutoField(Field)
- int自增列,必须填入参数 primary_key=True BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32) class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647 BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field)
- 布尔值类型 NullBooleanField(Field):
- 可以为空的布尔值 CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度 TextField(Field)
- 文本类型 EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为
192.0.2.1,开启此功能,需要protocol="both" URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字 UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹 FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field)
- 浮点型 DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度 BinaryField(Field)
- 二进制类型
字段合集
支持自定义字段
class UnsignedIntegerField(models.IntegerField):
def db_type(self, connection):
return 'integer UNSIGNED' PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)', 自定义一个无符号整数字段
自定义字段
自定义char类型字段
(查看类model.Field下的626行)
from django.db import models # Create your models here.
class FixedCharField(models.Field):
'''
自定义char类型的字段类
'''
def __init__(self, max_length, *args, **kwargs):
super().__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection):
'''
限制生成数据库的表的字段为char,长度为指定的max_length
:param connection:
:return:
'''
return 'char(%s)' % self.max_length class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
# 使用自定义的char定义字段,并指定长度
# 描述
des = FixedCharField(max_length=64)
自定义char类型
附录:
ORM字段与数据库中实际字段的对应关系
4.字段参数
null 用于表示某个字段可以为空
unique 如果设置为unique=True 则该字段在此表中必须是唯一的
db_index 如果db_index=True 则代表着为此字段设置索引
default 为该字段设置默认值
5.DateField和DateTimeField
auto_now_add 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库
auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段
6.关系字段
1)ForeignKey,外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系
字段参数
to 设置要关联的表
to_field 设置要关联的表的字段
related_name 反向操作时,使用的字段名,用于代替原反向查询时的_set
related_query_name 反向查询操作时,使用的连接前缀,用于替换使用双下划线查询时,双下滑线前的表名 on_delete 当删除关联表中的数据时,当前表与关联的行的行为
models.CASCADE 删除关联数据,与之关联也删除
models.DO_NOTHING 删除关联数据,引发错误integrityError
models.PROTECT 删除关联数据,引发错误ProtectedError
models.SET_NULL 删除关联数据,与之关联的值设置为null,前提是FK字段需要设置为空
models.SET_DEFAULT 删除关联数据,与之关联的值设置为默认值,前提是FK字段需要设置默认值
models.SET 删除关联数据
A.与之关联的值设置为指定值,设置:models.SET(值)
B.与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
示例:
准备书和出版社两张表
from django.db import models # Create your models here.
# 书
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
# 创建外键,关联publish
publisher = models.ForeignKey(to="Publisher", on_delete=models.CASCADE)
# 创建多对多关联author
author = models.ManyToManyField(to="Author") def __str__(self):
return self.title # 出版社
class Publisher(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32) def __str__(self):
return self.name
查询某个出版社关联的所有书籍---反向查找,查新方法:
models.Publisher.objects.get(id='').book_set.all()
当在ForeignKey字段中添加related_name参数之后,查询方法:
# 书
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
# 创建外键,关联publish
publisher = models.ForeignKey(to="Publisher", on_delete=models.CASCADE, related_name='books')
# 创建多对多关联author
author = models.ManyToManyField(to="Author") def __str__(self):
return self.title
models.Publisher.objects.get(id='').books.all()
2)OneToOneField,一对一字段,通常用来扩展已有字段
一对一关联关系多用在一张表的不同字段查询频次差距过大的情况下,将本可以存储在一张表的字段拆分成两张表,然后建立一对一关系
字段参数
to 设置要关联的表。
to_field 设置要关联的字段
on_delete 同ForeignKey字段
# 作者
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
phone = models.CharField(max_length=11)
detail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE) def __str__(self):
return self.name # 作者详情
class AuthorDetail(models.Model):
addr = models.CharField(max_length=64)
email = models.EmailField()
3)ManyToMangField,多对多关联关系,在数据库中通过建立第三张表建立关联关系
字段参数
to 设置要关联的表
related_name 同ForeignKey字段
related_query_name 同ForeignKey字段
symmetrical 仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True
through 在使用ManyToMany字段时,Django会自动生成一张管理多对多关联关系的表
同时也可以通过该参数创建来管理第三张表,需要该参数来制定第三张表的表名
through_fields 设置关联的字段
db_table 设置第三张表时,表的名称
示例:建立多对多关联关系的三种方法
方法一:自建第三张表,通过ForeignKey建立关联
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名") class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名") # 自建第三张表,通过外键关联书和作者
class Author2Book(models.Model):
author = models.ForeignKey(to="Author", on_delete=models.CASCADE)
book = models.ForeignKey(to="Book", on_delete=models.CASCADE) class Meta:
# 设置联合唯一
unique_together = ("author", "book")
方法二:通过ManyToManyField自动创建第三张表
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名") # 通过ORM自带的ManyToManyField自动创建第三张表
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名")
books = models.ManyToManyField(to="Book", related_name="authors")
方法三:通过ManyToManyField指定并自行创建第三张表
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名") # 自建第三张表,并通过ManyToManyField指定关联
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名")
books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
# through_fields接受一个2元组('field1','field2'):
# 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。 class Author2Book(models.Model):
author = models.ForeignKey(to="Author")
book = models.ForeignKey(to="Book") class Meta:
unique_together = ("author", "book")
补充说明:
当需要在第三张表中存储额外的字段时,就要使用第三种方法,但此时无法使用set、add、remove、clear方法来管理多对多关系,需要通过第三张表的model来管理
4)元信息,ORM对应的类里面包含另外一个元类Meta类,里面封装了一些数据库的信息
db_table ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名
index_together 联合索引
unique_together 联合唯一索引
ordering 指定默认按什么字段排序,只有设置了该属性,我们查询到的结果才可以被reverse()
Django框架详细介绍---模型---ORM的更多相关文章
- Django框架详细介绍---中间件(认证)
一.绪论 在cookie和session的应用中,通过在视图函数内添加装饰器判断用户是否登录,把没有登录的用户请求跳转到登录页面,通过给几个特定视图函数加装饰器实现了这个需求.但是以后添加的视图函数可 ...
- Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化
Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 引言 在数据库存在外键的其情况下,使用select_related()和pre ...
- Django框架详细介绍---ORM相关操作
Django ORM相关操作 官方文档: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ 1.必须掌握的十三个方法 <1& ...
- Django框架详细介绍---视图系统
Django视图系统 1.什么是视图 在Django中,一个视图函数/类,称为视图.实质就是一个用户自定义的简单函数,用来接收WEB请求并xing响应请求,响应的内容可以是一个HTML文件.重定向.一 ...
- Django框架详细介绍---cookie、session、自定义分页
1.cookie 在HTTP协议介绍中提到,该协议是无状态的,也就是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的 ...
- Django框架详细介绍---Admin后台管理
1.Admin组件使用 Django内集成了web管理工具,Django在启动过程中会执行setting.py文件,初始化Django内置组件.注册APP.添加环境变量等 # Application ...
- Django框架详细介绍---请求流程
Django请求流程图 1.客户端发送请求 2.wsgiref是Django封装的套接字,它将客户端发送过来的请求(请求头.请求体封装成request) 1)解析请求数据 2)封装响应数据 3.中间件 ...
- Django框架详细介绍---request对象
几个重要的函数 1.HttpRequest.get_host() 根据从HTTP_X_FORWARDED_HOST(如果打开 USE_X_FORWARDED_HOST,默认为False和 HTTP_H ...
- Django框架详细介绍---认证系统
在web开发中通常设计网站的登录认证.注册等功能,Django恰好内置了功能完善的用户认证系统 1.auth模块 from django.contrib import auth 模块源码 import ...
随机推荐
- 【原创】SAP/Oracle 集团企业海外全球化实施注意事项: 一带一路本地化 (持续更新)
ABC集团SAP的系统平台已经扩展到全球一百来个国家和地区,SAP系统平台的全球实施项目中, 当时是需要支持当地的业务和法律法规的合规要求. 当时客户也是缺乏当地的资源以及对当地法律法规和业务实践的了 ...
- ZOJ 3886 Nico Number(筛素数+Love(线)Live(段)树)
problemCode=3886">ZOJ 3886 题意: 定义一种NicoNico数x,x有下面特征: 全部不大于x且与x互质的数成等差数列,如x = 5 ,与5互素且不大于5的数 ...
- NuGet Packages are missing,This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.
错误内容 This project references NuGet package(s) that are missing on this computer. Use NuGet Package R ...
- 美客分销商城-接力购源码系统,全开源代码可进行二次开发,微信小程序分销商城
1. 准备服务器.域名(SSL证书).认证的微信小程序.微信支付商户号 2. 系统功能简介 三.演示案例,微信扫码查看 四.后台管理系统 五. 全套开源源码,进行二次开发 六.本系统完美运营,全套代码 ...
- Cocos2dx项目在各种IDE中新建类之后的可行编译方式
注:这里说可行,但是并不是最好的,只是可以完成编译. 1.linux+code::blocks下的cocos2dx项目新建一个类TestScene.h 新建的TestScene.h和TestScene ...
- 一、Sql Server 基础培训《进度1-建库建数据表(实际操作)》
知识点: 1.建数据库示例参考 --创建一个数据库名为‘dbtest’ create database dbtest go --打开数据库 dbtest use dbtest go 2.建表示例参考 ...
- Scikit-learn使用总结
在机器学习和数据挖掘的应用中,scikit-learn是一个功能强大的python包.在数据量不是过大的情况下,可以解决大部分问题.学习使用scikit-learn的过程中,我自己也在补充着机器学习和 ...
- poj3255 Roadblocks
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13594 Accepted: 4783 Descr ...
- Nest.js 拦截器
Docs: https://docs.nestjs.com/interceptors 该对象包含从路由处理程序返回的值 在方法执行之前/之后绑定额外的逻辑 转换函数返回的结果 转换从函数抛出的异常 / ...
- Nestjs 上传文件
Docs: https://docs.nestjs.com/techniques/file-upload 上传单文件 @Post('upload') @UseInterceptors(FileInte ...