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. 一、Mongodb安装和配置

    简介 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品. Mongod ...

  2. Go Module下使用本地包

    介绍两种方式: 方式一(推荐): 严格的说,方式一是使用项目目录下的go文件. 项目目录如下: |── studyModule //项目主目录 | |──log //主目录下文件夹 | | |──lo ...

  3. VMware克隆Linux虚拟机报错

    在VMware里克隆了2个centos6.5,执行命令重启网卡服务报以下错误: Bringing up interface eth0: Device eth0 does not seem to be ...

  4. 国产安全自主可控IT智能运维管理解决方案

    新一轮科技革命和产业变革席卷全球,大数据.云计算.物联网.人工智能.区块链等新技术不断涌现,数字经济正深刻地改变着人类的生产和生活方式,作为经济增长新动能的作用日益凸显.伴随增长的,还有网络中不断涌现 ...

  5. 工作五年的.neter的一些经历感想和对未来的一些疑惑

    本次疫情在家办公快一个月了,节省了上下班的时间,外出活动时间,感觉有好多时间可以利用.人一闲下来就容易想事情,很多事情想不通心里堵的厉害,做事都提不起兴趣.至于想些什么呢,我给大家摆一下. 我的经历 ...

  6. LINQ标准查询运算符的执行方式-即时

    即时,声明查询的位置立即执行.查询返回如果是不可以枚举的的结果,都会立即执行. 执行方式为“”即时”的查询运算符有下面这些. Aggregate 应用累计器函数和结果选择器,返回传入泛型类型TSour ...

  7. ES6 - 基础学习(3): 变量的解构赋值

    解构赋值概述 1.解构赋值是对赋值运算符的扩展. 2.它是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值. 3.代码书写上显得简洁且易读,语义更加清晰明了:而且还方便获取复杂对象中的数据字 ...

  8. centos7使用fdisk:创建和维护MBR分区表

    1.在VMware选择要添加硬盘的虚拟机,添加一块硬盘. 这样就有两块硬盘 2.重启虚拟机. cd /dev #dev是设备目录,下面有很多很多设备,其中就包含硬盘 ll grep | sd #过滤s ...

  9. hadoop完全分布式部署

    1.我们先看看一台节点的hdfs的信息:(已经安装了hadoop的虚拟机:安装hadoophttps://www.cnblogs.com/lyx666/p/12335360.html) start-d ...

  10. PMP--1.7 项目治理

    治理凌驾于管理之上 组织治理用于影响项目治理. 组织治理需要组织根据组织文化.项目类型和组织需求裁剪治理框架,适用于当前组织. 其实组织治理的内容,在项目管理初期不需要详细了解,组织治理的内容都是高层 ...