Object Relational Mapping (ORM)

orm介绍

orm概念

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

orm由来

让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。

几乎所有的软件开发过程中都会涉及到对象和关系数据库。在用户层面和业务逻辑层面,我们是面向对象的。当对象的信息发生变化的时候,我们就需要把对象的信息保存在关系数据库中。

按照之前的方式来进行开发就会出现程序员会在自己的业务逻辑代码中夹杂很多SQL语句用来增加、读取、修改、删除相关数据,而这些代码通常都是重复的。

orm的优势

ORM解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。

ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。

让软件开发人员专注于业务逻辑的处理,提高了开发效率。

orm的劣势

ORM的缺点是会在一定程度上牺牲程序的执行效率。

ORM用多了SQL语句就不会写了,关系数据库相关技能退化...

orm总结

ORM只是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。

但我们不能指望某个工具能一劳永逸地解决所有问题,一些特殊问题还是需要特殊处理的。

但是在整个软件开发过程中需要特殊处理的情况应该都是很少的,否则所谓的工具也就失去了它存在的意义。

Django中的ORM

django项目使用mysql数据库

1. 在Django项目的settings.py文件中,配置数据库连接信息:

DATABASES = {
#配置mysql
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "你的数据库名称", # 需要自己手动创建数据库
"USER": "数据库用户名",
"PASSWORD": "数据库密码",
"HOST": "数据库IP",
"POST": 3306
}
#配置sqlite3
'default2': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

2. 在Django项目的__init__.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库:

import pymysql

pymysql.install_as_MySQLdb()

Model

快速入门

下面这个例子定义了一个 Person 模型,包含 first_name 和 last_name

from django.db import models

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)

first_name 和 last_name 是模型的字段。每个字段被指定为一个类属性,每个属性映射到一个数据库列。

上面的 Person 模型将会像这样创建一个数据库表:

CREATE TABLE myapp_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);

一些说明:

  • 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时。
  • id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。
  • 本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句。
  • Django支持MySQL5.5及更高版本。

Django ORM常用字段和参数

常用字段

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'

自定义char类型字段

class FixedCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
super().__init__(max_length=max_length, *args, **kwargs)
self.length = max_length def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为length指定的值
"""
return 'char(%s)' % self.length class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用上面自定义的char类型的字段
cname = FixedCharField(max_length=25)

附ORM字段与数据库实际字段的对应关系

对应关系:
'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)', 对应关系

字段参数

null

用于表示某个字段可以为null,默认不为null

unique

如果设置为unique=True 则该字段在此表中必须是唯一的 。

db_index

如果db_index=True 则代表着为此字段设置数据库索引。

default

为字段设置默认值

时间字段独有

DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性

auto_now_add

配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

auto_now

配置上auto_now=True,每次更新数据记录的时候会更新该字段。

关系字段

ForeignKey

外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。

ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。

字段参数

to

设置要关联的表

to_field

设置要关联的字段

on_delete

设置约束规则

MangToManyFiield

用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系。

字段参数

to

设置要关联的字段

related_name

用于外键反向查询,代替book__set,添加后book_set将不能用。

例:

#出版社
class Publisher(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=64,unique=True)
addr=models.CharField(max_length=128)
def __str__(self):
return "<Publisher Object:{}>".format(self.name) #书
class Book(models.Model):
id=models.AutoField(primary_key=True)
title=models.CharField(max_length=64,unique=True)
price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
publisher=models.ForeignKey(
to="Publisher",
related_name='books',#用于外键反向查询,代替book__set,添加后book_set将不能用。
on_delete=True,
) #查询语句
f5= publisher_obj.books.all()

related_query_name

related_query_name="oo",#用于双下方法反向查询

例:

#出版社
class Publisher(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=64,unique=True
def __str__(self):
return "<Publisher Object:{}>".format(self.name) #书
class Book(models.Model):
id=models.AutoField(primary_key=True)
title=models.CharField(max_length=64,unique=True)
price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
publisher=models.ForeignKey(
to="Publisher",
related_query_name="oo",#用于双下方法查询
on_delete=True,
) #查询语句
f5=models.Publisher.objects.filter(id=1).values_list('oo__title')

symmetrical

仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。

例子:

class Person(models.Model):
name = models.CharField(max_length=16)
friends = models.ManyToManyField("self")

此时,person对象就没有person_set属性

class Person(models.Model):
name = models.CharField(max_length=16)
friends = models.ManyToManyField("self", symmetrical=False)

此时,person对象现在就可以使用person_set属性进行反向查询

through

在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。

但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。

through_fields

设置关联的字段

db_table

默认创建第三张表时,数据库中表的名称

多对多关联关系的三种方式

方式一:自动创建第三张表

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")
book = models.ForeignKey(to="Book") 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来管理多对多关系。

元信息

ORM对应的类里面包含另一个Meta类,而Meta类封装了一些数据库的信息。主要字段如下:

db_table

ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。

index_together

联合索引

例:

#     class Meta:
# # 建立联合约束
# unique_together = ("author", "book")

unique_together

联合唯一索引

例:

#     class Meta:
# # 建立联合唯一约束
# unique_together = ("author", "book")

ordering

指定默认按什么字段排序。

只有设置了该属性,我们查询到的结果才可以被reverse()。

django orm介绍以及字段和参数的更多相关文章

  1. Django中ORM介绍和字段及其参数

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  2. Django ORM介绍 和字段及字段参数

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  3. Django ORM中常用字段和参数

    一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...

  4. Django --ORM常用的字段和参数 多对多创建形式

    1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型 ...

  5. Django ORM常用的字段和参数

    ORM 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类 ...

  6. Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...

  7. 6月20日 Django中ORM介绍和字段、字段参数、相关操作

    一.Django中ORM介绍和字段及字段参数 二.Django ORM 常用字段和参数 三.Django ORM执行原生SQL.在Python脚本中调用Django环境.Django终端打印SQL语句 ...

  8. ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化

    聚合函数 名称 作用 Max() 最大值 Min() 最小值 Sum() 求和 Count() 计数 Avg() 平均值 关键字: aggregate 聚合查询通常都是配合分组一起使用的 关于数据库的 ...

  9. day07 ORM中常用字段和参数

    day07 ORM中常用字段和参数 今日内容 常用字段 关联字段 测试环境准备 查询关键字 查看ORM内部SQL语句 神奇的双下划线查询 多表查询前提准备 常用字段 字段类型 AutoField in ...

随机推荐

  1. 【TensorFlow】TensorFlow获取Variable值,将Variable保存为list数据

    Variable类型对象不能直接输出,因为当前对象只是一个定义. 获取Variable中的浮点数需要从数据流图获取: initial = tf.truncated_normal([3,3], stdd ...

  2. Ubuntu18 永久设置分辨率1920x1080

    起因 虚拟机(virtualBox)中设置 1920*1080 的分辨率后, 每次重启后都会回到默认,永久设置的方式如下 步骤: 添加系统设置 sudo xrandr --newmode " ...

  3. 如何查看SparkSQL 生成的抽象语法树?

    前言 在<Spark SQL内核剖析>书中4.3章节,谈到Catalyst体系中生成的抽象语法树的节点都是以Context来结尾,在ANLTR4以及生成的SqlBaseParser解析SQ ...

  4. ASP.NET Core MVC 中实现中英文切换

    哈喽..大家好 很久没有更新了,今天就来一篇最近开发用到的功能,那就是中英文切换,这个实际上也不是高大上,先说一下原理,在.NET Core框架中给我们提供了全球化的类,叫做Localization, ...

  5. 20200116--python学习第十天

    今日内容 1.参数 2.作用域 3.函数嵌套 内容回顾 线上操作系统:centos py2和py3的区别? 每种数据类型,列举你了解的方法. 3 or 9 and 8 字符串的反转 is 和 == 的 ...

  6. shell脚本 定期删除日志

    定期删除日志: 然后建立清除日志文件的shell脚本,文件名为clean_log只保留最近三天的日志     #! /bin/bashlogdir=/var/log/httpdcd ${logdir} ...

  7. 手把手带你阅读Mybatis源码(三)缓存篇

    前言 大家好,这一篇文章是MyBatis系列的最后一篇文章,前面两篇文章:手把手带你阅读Mybatis源码(一)构造篇 和 手把手带你阅读Mybatis源码(二)执行篇,主要说明了MyBatis是如何 ...

  8. ASP.NET Core ResponseCache进行缓存操作

    前言 本章将介绍客户端缓存将介绍浏览器缓存和服务端缓存,使用浏览器缓存将减少对web服务器的请求次数,同时可以提升性能,避免重复的运算浪费. ASP.NET Core对于HTTP缓存分为两种: 客户端 ...

  9. 网络模块axios的简单应用

    一.axios的基本使用 例子中使用到的url仅作为示例,不一定有效,想要复现代码需要使用能够提供数据的有效服务器接口url 1.1.什么是axios axios:ajax i/o system:是用 ...

  10. OptaPlanner 7.32.0.Final版本彩蛋 - SolverManager之批量求解

    上一篇介绍了OptaPlanner 7.32.0.Final版本中的SolverManager接口可以实现异步求解功能.本篇将继续介绍SolverManager的另一大特性 - 批量求解. 适用场景 ...