作者们就须要把对象的新闻保存在关周详据库中
Tagged Tags:

Object Relational Mapping(ORM)

ORM介绍

ORM概念

指标关系映射(Object Relational
Mapping,简单的称呼ORM卡塔尔国方式是后生可畏种为了消除面向对象与关周密据仓库储存在的互不相称的场景的技艺。

简易的说,ORM是由此选用描述对象和数据库之间映射的元数据,将次第中的对象活动长久化到关周密据库中。

ORM在专门的学问逻辑层和多少库层之间充作了大桥的作用。

ORM由来

让大家从O/PRADO开始。字母O源点于”对象”(Object),而纳瓦拉则来自于”关系”(Relational)。

差一些全部的软件开垦进程中都会涉及到目标和关周全据库。在顾客规模和业务逻辑层面,大家是面向对象的。当目的的音讯爆发变化的时候,大家就须求把目的的音信用保证存在关周到据库中。

坚决守住事先的方法来展费用付就能够出现工程师会在投机的职业逻辑代码中掺杂过多SQL语句用来充实、读取、修正、删除相关数据,而那么些代码常常都以重新的。

ORM的优势

ORM解决的最首要难题是指标和涉嫌的映照。它日常把一个类和四个表逐项对应,类的每一种实例对应表中的一条记下,类的各类属性对应表中的每一个字段。 

ORM提供了对数据库的炫彩,不用直接编写SQL代码,只需像操作对象近似从数据库操作数据。

让软件开辟职员注意于业务逻辑的拍卖,进步了成本功能。

ORM总结

ORM只是大器晚成种工具,工具确实能一挥而就部分再次,轻便的麻烦。那是无庸置疑的。

但大家不可能指望有个别工具能一劳永逸地缓慢解决所极度,一些奇特难点只怕须求特殊管理的。

可是在漫天软件开垦进程中要求特殊管理的气象应该都以很少的,不然所谓的工具也就错失了它存在的含义。

Django中的ORM

Django项目接收MySQL数据库

  1. 在Django项指标settings.py文件中,配置数据库连接消息:

    DATABASES = {
      ’default’: {
        ’ENGINE’: ‘django.db.backends.mysql’, # 连接的数据库类型
        ’NAME’: ‘name’, # 数据库名称
        ’HOST’: ‘127.0.0.1’, # 连接数据库之处     ’PORT’: 3306, # 端口
        ’USE君越’: ‘root’, # 顾客名
        ’PASSWO途乐D’: ‘123456’, # 密码
      }
    }

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

import pymysql

pymysql.install_as_MySQLdb()

Model

在Django中model是您多少的单一、明显的新闻来自。它饱含了您存款和储蓄的数额的根本字段和行为。平常,多少个模型(model卡塔 尔(英语:State of Qatar)映射到三个数额库表,

主导情形:

  • 每一种模型都以一个Python类,它是django.db.models.Model的子类。
  • 模型的各种属性都意味着三个数据库字段。
  • 综合,Django为你提供了三个自动生成的数据库访问API,详询合罗马尼亚语档链接。

图片 1

快快入门

上面那几个事例定义了一个 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()实例。

字段合集

图片 2图片 3

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

自定义无符号整数字段

    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)',

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
FixedChar菲尔德(models.Field):

class FixedCharField(models.Field):
    """
    自定义的char类型的字段类
    """
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)

    def db_type(self, connection):
        """
        限定生成数据库表的字段类型为char,长度为max_length指定的值
        """
        return 'char(%s)' % self.max_length

class Person(models.Model):
    # 使用自定义的char类型的字段
    name = FixedCharField(max_length=32)
    age = models.IntegerField()
    birthday = models.DateField()

始建的表结构:

图片 4

字段参数

null

用于表示有些字段可感到空。

unique

纵然设置为unique=True 则该字段在那表中必需是当世无双的 。

db_作者们就须要把对象的新闻保存在关周详据库中。index

如果db_index=True 则表示着为此字段设置索引。

default

作者们就须要把对象的新闻保存在关周详据库中。为该字段设置默许值。

DateField和DateTimeField

作者们就须要把对象的新闻保存在关周详据库中。auto_now_add

配置auto_now_add=True,成立数量记录的时候会把这段日子光阴累积到数据库。

auto_now

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

论及字段

ForeignKey

外键类型在ORM中用来表示外键关联关系,常常把ForeignKey字段设置在
‘风度翩翩对多’中’多’的一方。

ForeignKey能够和其余表做涉嫌关系并且也能够和自己做涉嫌关系。

字段参数

to

安装要涉及的表

to_field

安装要涉及的表的字段

related_name

反向操作时,使用的字段名,用于代替原反向查询时的’表名_set’。

例如:

class Classes(models.Model):
    name = models.CharField(max_length=32)

class Student(models.Model):
    name = models.CharField(max_length=32)
    theclass = models.ForeignKey(to="Classes")

当我们要询问某些班级关联的全部学生(反向查询卡塔尔时,大家会这样写:

models.Classes.objects.first().student_set.all()

当大家在ForeignKey字段中加多了参数 related_name 后,

class Student(models.Model):
    name = models.CharField(max_length=32)
    theclass = models.ForeignKey(to="Classes", related_name="students")

当大家要询问有些班级关联的有着学子(反向查询卡塔 尔(阿拉伯语:قطر‎时,我们会这么写:

models.Classes.objects.first().students.all()

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(可进行对象)

def func():
    return 10

class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id",
        on_delete=models.SET(func)
    )

db_constraint

是还是不是在数据库中创制外键约束,默以为True。 

OneToOneField

生机勃勃对一字段。

日常一对一字段用来扩大原来就有字段。

一定的关联关系多用在当一张表的两样字段查询频次差别过大的状态下,将本得以积攒在一张表的字段拆开放置在两张表中,然后将两张表创设生龙活虎对风流洒脱的关联关系。

class Author(models.Model):
    name = models.CharField(max_length=32)
    info = models.OneToOneField(to='AuthorInfo')


class AuthorInfo(models.Model):
    phone = models.CharField(max_length=11)
    email = models.EmailField()

字段参数

to

安装要涉及的表。

to_field

安装要涉及的字段。

on_delete

同ForeignKey字段。

ManyToManyField

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

字段参数

to

设置要提到的表。

related_name

同ForeignKey字段。

related_query_name

同ForeignKey字段。

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")

办法三:设置Many汤姆anyField并点名自行创设的第三张表

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来管理多对多涉及。

元信息

db_table

ORM在数据库中的表名默许是 app_类名,能够经过db_table能够重写表名。

index_together

一起索引。

unique_together

三只独一索引。

ordering

钦命默许按如何字段排序。

唯有设置了该属性,大家询问到的结果才得以被reverse()。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注