Django's ORM (a)

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


  1. 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',
}


  1. 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即可查看查询语句,具体操作如下:

img


Guess you like

Origin www.cnblogs.com/cjwnb/p/11795845.html