对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。mysql
简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。程序员
ORM在业务逻辑层和数据库层之间充当了桥梁的做用。sql
让咱们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。数据库
几乎全部的软件开发过程当中都会涉及到对象和关系数据库。在用户层面和业务逻辑层面,咱们是面向对象的。当对象的信息发生变化的时候,咱们就须要把对象的信息保存在关系数据库中。django
按照以前的方式来进行开发就会出现程序员会在本身的业务逻辑代码中夹杂不少SQL语句用来增长、读取、修改、删除相关数据,而这些代码一般都是重复的。后端
ORM解决的主要问题是对象和关系的映射。它一般把一个类和一个表一一对应,类的每一个实例对应表中的一条记录,类的每一个属性对应表中的每一个字段。 app
ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操做对象同样从数据库操做数据。ide
让软件开发人员专一于业务逻辑的处理,提升了开发效率。工具
ORM的缺点是会在必定程度上牺牲程序的执行效率。spa
ORM用多了SQL语句就不会写了,关系数据库相关技能退化...
ORM只是一种工具,工具确实能解决一些重复,简单的劳动。这是不能否认的。
但咱们不能期望某个工具能一劳永逸地解决全部问题,一些特殊问题仍是须要特殊处理的。
可是在整个软件开发过程当中须要特殊处理的状况应该都是不多的,不然所谓的工具也就失去了它存在的意义。
1. 在Django项目的settings.py文件中,配置数据库链接信息:
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "你的数据库名称", # 须要本身手动建立数据库 "USER": "数据库用户名", "PASSWORD": "数据库密码", "HOST": "数据库IP", "POST": 3306 } }
2. 在Django项目的__init__.py文件中写以下代码,告诉Django使用pymysql模块链接MySQL数据库:
import pymysql pymysql.install_as_MySQLdb()
在Django中model是你数据的单1、明确的信息来源。它包含了你存储的数据的重要字段和行为。一般,一个模型(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 );
一些说明:
int自增列,必须填入参数 primary_key=True。当model中若是没有自增列,则自动会建立一个列名为id的列。
一个整数类型,范围在 -2147483648 to 2147483647。
字符类型,必须提供max_length参数, max_length表示字符长度。
日期字段,日期格式 YYYY-MM-DD,至关于Python中的datetime.date()实例。 ##这个只有年月日
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至关于Python中的datetime.datetime()实例。 ##这个是带时间的 须要有auto_now_add=TRue 须要或者参数,在添加数据的时候,这个值把当前的时候存进去
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): 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 Class(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=25) # 使用自定义的char类型的字段 cname = FixedCharField(max_length=25)
建立的表结构:
附ORM字段与数据库实际字段的对应关系
用于表示某个字段能够为空。
若是设置为unique=True 则该字段在此表中必须是惟一的 。
若是db_index=True 则表明着为此字段设置索引。
为该字段设置默认值。
配置auto_now_add=True,建立数据记录的时候会把当前时间添加到数据库。
配置上auto_now=True,每次更新数据记录的时候会更新该字段。
外键类型在ORM中用来表示外键关联关系,通常把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey能够和其余表作关联关系同时也能够和自身作关联关系。
设置要关联的表
设置要关联的表的字段
反向操做时,使用的字段名,用于代替原反向查询时的'表名_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()
反向查询操做时,使用的链接前缀,用于替换表名。
当删除关联表中的数据时,当前表与其关联的行的行为。
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) )
是否在数据库中建立外键约束,默认为True。
一对一字段。
一般一对一字段用来扩展已有字段。
设置要关联的表。
设置要关联的字段。
同ForeignKey字段。
用于表示多对多的关联关系。在数据库中经过第三张表来创建关联关系。
##第三张表的好处是能够为之后增长一些信息更方便。
##第三张表须要指定外键这样才能够
## 第三张表的字段名字不能加id
设置要关联的表
同ForeignKey字段。
同ForeignKey字段。
仅用于多对多自关联时,指定内部是否建立反向操做的字段。默认为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属性进行反向查询。
在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。
但咱们也能够手动建立第三张表来管理多对多关系,此时就须要经过through来指定第三张表的表名。
设置关联的字段。 ##这个是在手动建立第三张表,有了Book2Author这个类之后才使用这个参数。
class Book(models.Model): title = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) # books = models.ManyToManyField( to="Book", through="Book2Author", through_fields=('author', 'book') ) # 本身建立第三张表 class Book2Author(models.Model): id = models.AutoField(primary_key=True) book = models.ForeignKey(to=Book) author = models.ForeignKey(to=Author) first_blood = models.DateField()
默认建立第三张表时,数据库中表的名称。
ORM对应的类里面包含另外一个Meta类,而Meta类封装了一些数据库的信息。主要字段以下:
ORM在数据库中的表名默认是 app_类名,能够经过db_table能够重写表名。
联合索引。
联合惟一索引。
指定默认按什么字段排序。
只有设置了该属性,咱们查询到的结果才能够被reverse()。