Django-ORM table building

Posted by jagat21 on Sat, 20 Jul 2019 07:40:52 +0200

Foreplay

ORM (Object Relational Mapping) is a technology to solve the mismatch between object-oriented and relational database.

Advantages of ORM:

The main problem that ORM solves is the mapping of objects and relationships. It usually corresponds one class to one table, each instance of a class corresponds to a record in the table, and each attribute of a class corresponds to each field in the table. -

ORM provides a mapping of the database. It does not need to write SQL code directly. It only needs to manipulate objects to manipulate the data of the database.

Let software developers concentrate on the processing of business logic, improve the efficiency of development.

 

ORM's disadvantage:

The disadvantage of ORM is that it will sacrifice the efficiency of program execution to some extent.

ORM operations are limited, that is, ORM defined operations can be completed, some complex query operations can not be completed.

ORM will not write with more SQL statements, and the skills related to relational database will deteriorate.

ORM Creates Data Table

1. In the settings.py file of Django project, configure database connection information:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "Your database name",  # You need to create your own database manually
        "USER": "Database username",
        "PASSWORD": "Database password",
        "HOST": "data base IP",
        "POST": 3306
 } }

2. Write the following code in the _init_ py file under the directory with the same name as Django project, telling Django to connect MySQL database with pymysql module:

import pymysql
 
pymysql.install_as_MySQLdb()
  • Each table is a python class, which is a subclass of Django.db.models.Model
  • Each attribute of the model represents a database field
  • The object of the model represents a row of data

The following code creates a person's data table

from django.db import models

class Person(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    birth = models.DateTimeField(auto_now_add=True)

Some notes:

  • The name of the table myapp_person is automatically generated. If you want to customize the table name, you need to specify the db_table parameter in the Meta class of the model. It is strongly recommended to use the lowercase table name, especially when using MySQL as the database.
  • The ID field is automatically added. If you want to specify a custom primary key, you just need to specify primary_key=True in one of the fields. If Django finds that you have explicitly set Field.primary_key, it will not add an automatic ID column.

Field

AutoField

The self-increasing shaping field, the required parameter primary_key=True, becomes the primary key of the database. Without this field, django automatically creates a model that cannot have two AutoField fields.

IntegerField

An integer type. The range of values is - 2147483648 to 2147483647.

CharField

The max_length parameter must be provided for the character type. Max_length denotes the length of a character.

DateField

Date type, date format YYYY-MM-DD, equivalent to the instance of datetime.date in Python.

Parameters:

  • auto_now: Modify to the current date and time each time you modify it. No matter which field is modified, the time will change.
  • auto_now_add: The current date and time are automatically added when a new object is created. When modifying other fields, the time will not change

The auto_now and auto_now_add and default parameters are mutually exclusive and cannot be set at the same time.

DatetimeField

The date and time field, in YYYY-MM-DD HH: MM [: SS [. uuuuuu] [TZ], is equivalent to the instance of datetime.datetime in Python.

Parameters:

  • auto_now: Modify to the current date and time each time you modify it. No matter which field is modified, the time will change.
  • auto_now_add: The current date and time are automatically added when a new object is created. When modifying other fields, the time will not change
  1 AutoField(Field)
  2 - int self-incremental column, must fill in the parameter primary_key=True
  3 
  4     BigAutoField(AutoField)
  5 - bigint self-adding column, must fill in parameter primary_key=True
  6 
  Note: If there is no self-adding column in the model, a column named id is automatically created.
  8         from django.db import models
  9 
 10         class UserInfo(models.Model):
 11 # Automatically creates an integer column named id that is self-incremental
 12             username = models.CharField(max_length=32)
 13 
 14         class Group(models.Model):
 15 # Custom Self-Addendum
 16             nid = models.AutoField(primary_key=True)
 17             name = models.CharField(max_length=32)
 18 
 19     SmallIntegerField(IntegerField):
 20 - Small integers - 32768 - 32767
 21 
 22     PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 23 - Positive decimal integers 0 - 32767
 24 
 25     IntegerField(Field)
 26 - Integer Series (Signed) - 2147483648 - 2147483647
 27 
 28     PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 29 - Positive integers 0 - 2147483647
 30 
 31     BigIntegerField(IntegerField):
 32 - Long Integer (Signed) - 9223372036854775808 - 9223372036854775807
 33 
 34     BooleanField(Field)
 35 - Boolean Value Type
 36 
 37     NullBooleanField(Field):
 38 - Boolean values that can be empty
 39 
 40     CharField(Field)
 41 - Character type
 42 - Must provide max_length parameter, max_length represents character length
 43 
 44     TextField(Field)
 45 - Text type
 46 
 47     EmailField(CharField): 
 48 - String type, Django Admin and ModelForm provide validation mechanisms
 49 
 50     IPAddressField(Field)
 51 - String type, Django Admin and ModelForm provide verification mechanism for IPV4
 52 
 53     GenericIPAddressField(Field)
 54 - String type, Django Admin and ModelForm provide validation for Ipv4 and Ipv6
 55 - Parameters:
 56 protocol for specifying Ipv4 or Ipv6,'both','ipv4','ipv6'
 57 unpack_ipv4, if specified as True, then input: ffff:192.0.2.1, resolvable to 192.0.2.1. To turn on this function, you need protocol="both"
 58 
 59     URLField(CharField)
 60 - String type, Django Admin and ModelForm provide validation URL s
 61 
 62     SlugField(CharField)
 63 - String type, Django Admin and ModelForm provide validation support for letters, numbers, underscores, connectors (minus sign)
 64 
 65     CommaSeparatedIntegerField(CharField)
 66 - String type, format must be comma-separated digits
 67 
 68     UUIDField(Field)
 69 - String type, Django Admin and ModelForm provide validation of UUID format
 70 
 71     FilePathField(Field)
 72 - Strings, Django Admin, and ModelForm provide the ability to read files under folders
 73 - Parameters:
 74 path, folder path
 75 match = None, regular match
 76 recursive = False, recursive folder
 77 allow_files = True, allow files
 78 allow_folders = False, allow folders
 79 
 80     FileField(Field)
 81 - String, path saved in database, file uploaded to specified directory
 82 - Parameters:
 83 upload_to = save path of upload file
 84 storage = None storage component, default django. core. files. storage. FileSystem Storage
 85 
 86     ImageField(FileField)
 87 - String, path saved in database, file uploaded to specified directory
 88 - Parameters:
 89 upload_to = save path of upload file
 90 storage = None storage component, default django. core. files. storage. FileSystem Storage
 91 width_field = None, the highly saved database field name (string) of the uploaded image
 92 height_field = None upload image width saved database field name (string)
 93 
 94     DateTimeField(DateField)
 95-Date + Time Format YYYY-MM-DD HH: MM [: SS [. uuuuuu] [TZ]
 96 
 97     DateField(DateTimeCheckMixin, Field)
 98-Date Format YYYY-MM-DD
 99 
100     TimeField(DateTimeCheckMixin, Field)
101 - Time format HH: MM [: SS [. uuuuuuu]]
102 
103     DurationField(Field)
104 - Long integer, time interval, stored as bigint in database, the value obtained in ORM is datetime.timedelta type
105 
106     FloatField(Field)
107 - Floating Point Type
108 
109     DecimalField(Field)
110 - 10 decimal
111 - Parameters:
112 max_digits, total decimal length
113 decimal_places, decimal length
114 
115     BinaryField(Field)
116 - Binary type
117 
118 field type
Other fields

Official website

Custom fields

Customize a char type field:

class MyCharField(models.Field):
    """
    Customized field class of char type, inheriting models.Field
    """

    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):
        """
        Restrict the field type of the generated database table to char and the length to the value specified by max_length
        """
        return 'char(%s)' % self.max_length
Use custom char type fields:
 
from django.db import models

# Create your models here.
class MyCharField(models.Field):
    """
    //Customized field class of char type, inheriting models.Field
    """

    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):
        """
        //Restrict the field type of the generated database table to char and the length to the value specified by max_length
        """
        return 'char(%s)' % self.max_length

class Person(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() birth = models.DateTimeField(auto_now_add=True) phone = MyCharField(max_length=11)

Corresponding relationship between Django field and data table field type

class UnsignedIntegerField(models.IntegerField):
    def db_type(self, connection):
        return 'integer UNSIGNED'

# PS: The return value is the property of the field in the database.
# Django Fields correspond to database field types as follows:
    '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)',

Field parameters

The above is just a field created. What parameters can the field put? The following are commonly used

null              # Can fields in the database be null
db_column          # The column name of the field in the database. ORM The operation is written in the class, which is convenient to change the field name in the database.
default            # Default values of fields in the database
primary_key         # Is the field in the database the primary key?
db_index           # Can fields in the database be indexed
unique             # Can fields in a database be indexed uniquely
unique_for_date      # Can the field [date] part of the database be indexed uniquely?
unique_for_month     # Can the field [month] part of the database be indexed uniquely?
unique_for_year      # Can the field [year] part of the database be indexed uniquely?

verbose_name       # Admin The name of the field shown in the
blank           # Admin Is user input allowed to be null in
editable          # Admin Is it editable in
help_text         # Admin The prompt information for this field in
choices           # Admin In order to avoid cross-table operations, the contents of the selection box are displayed and stored in memory with unchanged data, such as: gf = models.IntegerField(choices=[(0, 'He Sui'), (1, 'Cousin'), ], default=1)

error_messages     # Customize error information (dictionary type) to customize the error information you want to display.
                  # Dictionary Jian: null, blank, invalid, invalid_choice, unique, and unique_for_date For example:{'null': "Can't be empty.", 'invalid': 'Format error'}

validators     # Customize error validation (list type) to customize the desired validation rules
      from django.core.validators import RegexValidator
      from django.core.validators import EmailValidator, URLValidator, DecimalValidator, \
        MaxLengthValidator, MinLengthValidator, MaxValueValidator, MinValueValidator

//For example:
test = models.CharField(
    max_length=32,
    error_messages={
        'c1': 'Priority error information 1',
        'c2': 'Priority error information 2',
        'c3': 'Priority error information 3',
    },
    validators=[
        RegexValidator(regex='root_\d+', message='Wrong', code='c1'),
        RegexValidator(regex='root_112233\d+', message='Another mistake', code='c2'),
        EmailValidator(message='Another mistake', code='c3'), ]
)

Model Meta parameter

class UserInfo(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32)

    class Meta:
        # Default table name generated in database app Name + Underline + Class name, if written below book,Then the data table is called book
        db_table = "table_name"

        # admin Table name shown in
        verbose_name = 'Personal information'

        # verbose_name plus s
        verbose_name_plural = 'All user information'

        # Joint Index
        index_together = [
            ("pub_date", "deadline"),  # Should be two existing fields
        ]

        # Joint Unique Index
        unique_together = (("driver", "restaurant"),)  # Should be two existing fields

Multi-table relationships and parameters

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
    to,                 # Table names to be associated
    to_field=None,      # The field name in the table to be associated
    on_delete=None,     # The behavior of the current table and its associated rows when data in the associated table is deleted
                        - models.CASCADE,Delete associated data and delete associated data
                        - models.DO_NOTHING,Delete associated data and cause errors IntegrityError
                        - models.PROTECT,Delete associated data and cause errors ProtectedError
                        - models.SET_NULL,Delete the associated data and set the associated value to null(premise FK Fields need to be set to null)
                        - models.SET_DEFAULT,Delete the associated data and set the associated value to the default value (premise) FK Fields need to set default values)
                        - models.SET,Delete the associated data,
                               a. The value associated with it is set to the specified value, setting: models.SET(value)
                               b. The value associated with it is set to the return value of the executable object, setting: models.SET(Executable object)
 
                                    def func():
                                        return 10
 
                                    class MyModel(models.Model):
                                        user = models.ForeignKey(
                                            to="User",
                                            to_field="id"
                                            on_delete=models.SET(func),)
    related_name=None,          # In reverse operation, the field name is used instead of the table name._set] For example: obj.Table Name_set.all()
    related_query_name=None,    # In reverse operation, the join prefix is used to replace the table name.     For example: models.UserGroup.objects.filter(Table Name__Field name=1).values('Table Name__Field name')
    limit_choices_to=None,      # stay Admin or ModelForm When displaying the associated data, the conditions provided are as follows:
                                # For example:
                        - limit_choices_to={'nid__gt': 5}
                        - limit_choices_to=lambda : {'nid__gt': 5}
 
                        from django.db.models import Q
                        - limit_choices_to=Q(nid__gt=10)
                        - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                        - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    db_constraint=True          # Whether to create foreign key constraints in the database
    parent_link=False           # stay Admin Whether the associated data is displayed in the
 
 
OneToOneField(ForeignKey)
    to,                 # Table names to be associated
    to_field=None       # The field name in the table to be associated
    on_delete=None,     # The behavior of the current table and its associated rows when data in the associated table is deleted
 
                        ###### For one to one ######
                        # 1. One-to-one is actually one-to-many. + unique index
                        # 2.When there is an inheritance relationship between two classes, a one-to-one field is created by default.
                        # The following will be A Add an extra one to the table c_ptr_id Column and only:
                                class C(models.Model):
                                    nid = models.AutoField(primary_key=True)
                                    part = models.CharField(max_length=12)
 
                                class A(C):
                                    id = models.AutoField(primary_key=True)
                                    code = models.CharField(max_length=1)
 
ManyToManyField(RelatedField)
    to,                         # Table names to be associated
    related_name=None,          # In reverse operation, the field name is used instead of the table name._set] For example: obj.Table Name_set.all()
    related_query_name=None,    # In reverse operation, the join prefix is used to replace the table name.     For example: models.UserGroup.objects.filter(Table Name__Field name=1).values('Table Name__Field name')
    limit_choices_to=None,      # stay Admin or ModelForm When displaying the associated data, the conditions provided are as follows:
                                # For example:
                                    - limit_choices_to={'nid__gt': 5}
                                    - limit_choices_to=lambda : {'nid__gt': 5}
 
                                    from django.db.models import Q
                                    - limit_choices_to=Q(nid__gt=10)
                                    - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                    - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    symmetrical=None,           # For many-to-many self-correlation only, symmetrical Fields used to specify whether to create reverse operations internally
                                # When doing the following, it is different. symmetrical There will be different optional fields
                                    models.BB.objects.filter(...)
 
                                    # Optional fields are: code, id, m1
                                        class BB(models.Model):
 
                                        code = models.CharField(max_length=12)
                                        m1 = models.ManyToManyField('self',symmetrical=True)
 
                                    # The optional fields are: bb, code, id, m1
                                        class BB(models.Model):
 
                                        code = models.CharField(max_length=12)
                                        m1 = models.ManyToManyField('self',symmetrical=False)
 
    through=None,               # When customizing the third table, use fields to specify relational tables
    through_fields=None,        # When customizing the third table, use fields to specify which fields in the relational table are used to do many-to-many relational tables
                                    from django.db import models
 
                                    class Person(models.Model):
                                        name = models.CharField(max_length=50)
 
                                    class Group(models.Model):
                                        name = models.CharField(max_length=128)
                                        members = models.ManyToManyField(
                                            Person,
                                            through='Membership',
                                            through_fields=('group', 'person'),
                                        )
 
                                    class Membership(models.Model):
                                        group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                        person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                        inviter = models.ForeignKey(
                                            Person,
                                            on_delete=models.CASCADE,
                                            related_name="membership_invites",
                                        )
                                        invite_reason = models.CharField(max_length=64)
    db_constraint=True,         # Whether to create foreign key constraints in the database
    db_table=None,              # The name of the table in the database when the third table is created by default

Topics: PHP Database Django Lambda MySQL