一、概述  

  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的更多相关文章

  1. Django框架详细介绍---中间件(认证)

    一.绪论 在cookie和session的应用中,通过在视图函数内添加装饰器判断用户是否登录,把没有登录的用户请求跳转到登录页面,通过给几个特定视图函数加装饰器实现了这个需求.但是以后添加的视图函数可 ...

  2. Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化

    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 引言 在数据库存在外键的其情况下,使用select_related()和pre ...

  3. Django框架详细介绍---ORM相关操作

    Django ORM相关操作 官方文档: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ 1.必须掌握的十三个方法 <1& ...

  4. Django框架详细介绍---视图系统

    Django视图系统 1.什么是视图 在Django中,一个视图函数/类,称为视图.实质就是一个用户自定义的简单函数,用来接收WEB请求并xing响应请求,响应的内容可以是一个HTML文件.重定向.一 ...

  5. Django框架详细介绍---cookie、session、自定义分页

    1.cookie 在HTTP协议介绍中提到,该协议是无状态的,也就是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的 ...

  6. Django框架详细介绍---Admin后台管理

    1.Admin组件使用 Django内集成了web管理工具,Django在启动过程中会执行setting.py文件,初始化Django内置组件.注册APP.添加环境变量等 # Application ...

  7. Django框架详细介绍---请求流程

    Django请求流程图 1.客户端发送请求 2.wsgiref是Django封装的套接字,它将客户端发送过来的请求(请求头.请求体封装成request) 1)解析请求数据 2)封装响应数据 3.中间件 ...

  8. Django框架详细介绍---request对象

    几个重要的函数 1.HttpRequest.get_host() 根据从HTTP_X_FORWARDED_HOST(如果打开 USE_X_FORWARDED_HOST,默认为False和 HTTP_H ...

  9. Django框架详细介绍---认证系统

    在web开发中通常设计网站的登录认证.注册等功能,Django恰好内置了功能完善的用户认证系统 1.auth模块 from django.contrib import auth 模块源码 import ...

随机推荐

  1. opencv wlsfilter depth refinement demo

    参考 https://docs.opencv.org/3.2.0/d3/d14/tutorial_ximgproc_disparity_filtering.html // This file is p ...

  2. Direct3D 11 Tutorial 7:Texture Mapping and Constant Buffers_Direct3D 11 教程7:纹理映射和常量缓冲区

    概述 在上一个教程中,我们为项目引入了照明. 现在我们将通过向我们的立方体添加纹理来构建它. 此外,我们将介绍常量缓冲区的概念,并解释如何使用缓冲区通过最小化带宽使用来加速处理. 本教程的目的是修改中 ...

  3. 使用 Postman 取得 Token 打另一隻 API

    使用 Postman 取得 Token 打另一隻 API Spring MVC token 统一校验和user 信息自动获取 使用token和SpringMVC来实现安全的RESTFul接口 spri ...

  4. Cesium高度解析

    var viewer = new Cesium.Viewer('cesiumContainer', { shadows : true }); //为true时,球体会有高程遮挡效果(在没有地形时候也会 ...

  5. selenium+chromedriver刷点击量

    #coding=utf-8 import re import time import json import requests from selenium import webdriver from ...

  6. java发送邮件无法显示图片 图裂 的解决办法

    package com.thinkgem.jeesite.common.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; ...

  7. Nodejs 使用Protobuf

    参考: Nodejs中使用Protobuf的.proto文件 为了在nodejs服务端使用proto 所以网上找了一些教程,这里实现下. 一 安装protobufjs 在服务端项目文件夹里shift+ ...

  8. Linux ReviewBoard安装与配置

    目录 0. 引言 1. 安装步骤 2. 配置站点 2.1 创建数据库 2.2 开始安装 2.3 修改文件访问权限 2.4 Web服务器配置 2.5 修改django相关配置 正文 回到顶部 0. 引言 ...

  9. Linux 的基本操作(系统的远程登录)

    系统的远程登录 首先要说一下,该部分内容对于linux初学者来讲并不是特别重要的,可以先跳过该章节,先学下一章,等学完后再回来看这一章. Linux大多应用于服务器,而服务器不可能像PC一样放在办公室 ...

  10. 微信小程序开发笔记01

    微信小程序开发的优势 1,不用安装,即开即用,用完就走.省流量,省安装时间,不占用桌面: 2,体验上虽然没法完全媲美原生APP,但综合考虑还是更优: 3,对于小程序拥有者来说,开发成本更低,他们可以更 ...