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