ORM Introduction
ORM concept
Object-Relational Mapping (Object Relational Mapping, referred ORM) to solve for the model is a phenomenon occurring not match each object relational database technology.
Simply put, by using the ORM metadata that describes the mapping between the object and the database, the program objects are automatically persisted to a relational database.
ORM between the business logic layer and the database layer acts as a bridge.
ORM-derived
Let's start with O / R. It originated in the letter O "subject" (Object), and R is derived from "relationship" (Relational).
Almost all of the software development process will involve objects and relational databases. At the user level and business logic plane, we are object-oriented. When information is subject to change, we need to target information stored in a relational database.
According to the previous approach to development will be mixed with programmers in their own business logic code many SQL statements to add, read, modify, delete data, and these codes are usually very similar or duplicate.
ORM advantage
The main problem ORM solution is to map objects and relationships. It is typically a class and a correspondence table, a record of each instance of the class corresponding to the table, each field corresponding to each attribute category table.
ORM provides a mapping to the database without writing SQL code directly, simply operation object data to the database will be able to operate.
Let software developers to focus on business logic processing, improve development efficiency.
ORM disadvantage
ORM drawback is that the efficiency of the program will be sacrificed to some extent.
ORM operation is limited, that is, ORM-defined operation is completed, some complex query operation is not complete.
ORM with more SQL statements would not have written, and relational database skills related degradation ...
ORM summary
ORM is only a tool, the tool can really solve some repetition, simple labor. This is undeniable.
But we can not expect a tool can solve all the problems once and for all, or some special problems that require special handling.
But throughout the software development process in cases that require special handling should all be very little, or so-called tool will be lost meaning of its existence
In Django ORM
Django project using MySQL database
- In Django project settings.py file, configure database connection information:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'cmdb1',
'HOST': '127.0.0.1',
'USER': 'root',
'PASSWORD': '123',
'PORT': 3306,
'CHARSET': 'utf8',
}
- Write the following code in __init__.py file in the directory with the same name in Django project, told Django uses pymysql modules connect to the MySQL database:
import pymysql
pymysql.install_as_MySQLdb()
Note: The database migration occurs when a warning
WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it.
OPTIONS add an extra parameter in the configuration : Django's official website explained (usually in the windows system only need to add such a sentence)
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
Model
In Django model is the single, definitive source of information for your data. It contains important field and behavior of your stored data. Typically, a model (Model) is mapped to a database table.
basic situation:
- Each model is a Python class that is a subclass of django.db.models.Model.
- Each attribute of the model represents a database field.
- In summary, Django provides you with an automatically generated database access API, for inquiry official document links .
how to use
It defines a Person model
from django.db import models
class Person(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, db_column='myname', verbose_name='姓名')
age = models.IntegerField(null=True, blank=True)
birth = models.DateTimeField(auto_now=True)
phone = MyCharField(max_length=11)
sex = models.IntegerField(choices=((1, '男'), (2, '女')))
class Meta:
# 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
db_table = "person"
# 在admin中的显示, 一般直接加verbose_name_plural
verbose_name = '个人信息' # 显示 个人信息s
verbose_name_plural = '所有用户信息' # 显示所有用户信息
# 联合索引
index_together = [('name', 'age')]
# 联合唯一索引
# unique_together = (("name", "age"))
# 排序
# ordering = ('age', )
def __str__(self):
return 'Person <{}:{}>'.format(self.id, self.name)
Description:
- Table app01_person names are automatically generated, if you want to customize the table name, you need to specify Meta class model in db_table parameters, it is strongly recommended to use lowercase table names, especially when using MySQL as the database.
- id field is added automatically, if you want to specify a custom primary key, just specify primary_key = True can be in one field. If Django find that you have explicitly set Field.primary_key, it will not automatically add the ID column.
- In this example using PostgreSQL CREATE TABLE SQL syntax formats, but it is worth noting that, Django will generate the corresponding SQL statement to the database according to the type specified in the configuration file.
- Django supports MySQL5.5 and later
Django ORM common fields and parameters
Common Fields
Auto Field
From the growing field of plastic surgery, a required parameter primary_key = True, then the primary key of the database. Without this field, django automatically created.
A model can not have two AutoField field.
IntegerField
An integer type. The range of values is -2147483648 to 2147483647.
CharField
Character type, you must provide max_length parameters. max_length represent characters in length.
DateField
Date type, date format YYYY-MM-DD, corresponding to the examples in Python datetime.date.
parameter:
- auto_now: each modification to the current date and time when the modification.
- auto_now_add: automatically add the current date and time when a new object is created.
auto_now and auto_now_add and default parameters are mutually exclusive, it can not be set simultaneously.
DatetimeField
Date time field, in the format YYYY-MM-DD HH: MM [: ss [.uuuuuu]] [TZ], corresponding to the examples in Python datetime.datetime.
Fields Collection
For details, click the query official website .
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)
- 二进制类型
ORM field and field correspondence between MySQL
对应关系:
'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)',
ORM字段与MySQL字段对应关系
Custom Fields
Custom a binary field, and the correspondence between database field and Django field type
class MyCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length
Use custom fields of type char:
class Person(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, db_column='myname', verbose_name='姓名')
age = models.IntegerField(null=True, blank=True)
birth = models.DateTimeField(auto_now=True)
phone = MyCharField(max_length=11)
sex = models.IntegerField(choices=((1, '男'), (2, '女')))
Table structure is created:
Field parameters
null
Is used to represent a field can be empty.
unique
If set to the unique = True field in this table must be unique.
db_index
If db_index = True represents the index field is set for this purpose.
default
Set the default value for the field
DateField和DateTimeField
auto_now_add
Configuring auto_now_add = True, create a data record when the current time will be added to the database
auto_now
Configuration auto_now = True, each time updating the data record will update the field
Relationship field
Field parameters
to
Set the table to be associated
to_field
To set the table associated fields
on_delete
When you delete data associated table, the current table row behavior associated with it.
models.CASCADE
Delete the associated data associated with it also deleted
db_constraint
Whether to create a foreign key constraint in the database, the default is True
The remaining field parameters
models.DO_NOTHING
删除关联数据,引发错误IntegrityError
models.PROTECT
删除关联数据,引发错误ProtectedError
models.SET_NULL
删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT
删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
models.SET
删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
OneToOneField
一对一字段。
通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)
字段参数
to
设置要关联的表。
to_field
设置要关联的字段。
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。(参考上面的例子)
一般操作
在进行一般操作时先配置一下参数,使得我们可以直接在Django页面中运行我们的测试脚本
在Python脚本中调用Django环境
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
import django
django.setup()
from app01 import models
这样就可以直接运行你的test.py文件来运行测试
Django终端打印SQL语句
如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看, 在Django项目的settings.py文件中,在最后复制粘贴如下代码:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
补充:
除了配置外,还可以通过.query即可查看查询语句,具体操作如下: