1. 程式人生 > >Object Relational Mapping(ORM)

Object Relational Mapping(ORM)

 

 

Object Relational Mapping(ORM)

ORM介紹

ORM概念

物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。

簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。

ORM在業務邏輯層和資料庫層之間充當了橋樑的作用。

ORM由來

讓我們從O/R開始。字母O起源於"物件"(Object),而R則來自於"關係"(Relational)。

幾乎所有的軟體開發過程中都會涉及到物件和關係資料庫。在使用者層面和業務邏輯層面,我們是面向物件的。當物件的資訊發生變化的時候,我們就需要把物件的資訊儲存在關係資料庫中。

按照之前的方式來進行開發就會出現程式設計師會在自己的業務邏輯程式碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關資料,而這些程式碼通常都是重複的。

ORM的優勢

ORM解決的主要問題是物件和關係的對映。它通常把一個類和一個表一一對應,類的每個例項對應表中的一條記錄,類的每個屬性對應表中的每個欄位。 

ORM提供了對資料庫的對映,不用直接編寫SQL程式碼,只需像操作物件一樣從資料庫操作資料。

讓軟體開發人員專注於業務邏輯的處理,提高了開發效率。

ORM的劣勢

ORM的缺點是會在一定程度上犧牲程式的執行效率。

ORM用多了SQL語句就不會寫了,關係資料庫相關技能退化...

ORM總結

ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不可否認的。

但我們不能指望某個工具能一勞永逸地解決所有問題,一些特殊問題還是需要特殊處理的。

但是在整個軟體開發過程中需要特殊處理的情況應該都是很少的,否則所謂的工具也就失去了它存在的意義。

Django中的ORM

Django專案使用MySQL資料庫

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

Model

在Django中model是你資料的單一、明確的資訊來源。它包含了你儲存的資料的重要欄位和行為。通常,一個模型(model)對映到一個數據庫表,

基本情況:

  • 每個模型都是一個Python類,它是django.db.models.Model的子類。
  • 模型的每個屬性都代表一個數據庫欄位。
  • 綜上所述,Django為您提供了一個自動生成的資料庫訪問API,詳詢官方文件連結

 

快速入門 

下面這個例子定義了一個 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
);

一些說明:

  • 表myapp_person的名稱是自動生成的,如果你要自定義表名,需要在model的Meta類中指定 db_table 引數,強烈建議使用小寫表名,特別是使用MySQL作為後端資料庫時。
  • id欄位是自動新增的,如果你想要指定自定義主鍵,只需在其中一個欄位中指定 primary_key=True 即可。如果Django發現你已經明確地設定了Field.primary_key,它將不會新增自動ID列。
  • 本示例中的CREATE TABLE SQL使用PostgreSQL語法進行格式化,但值得注意的是,Django會根據配置檔案中指定的資料庫後端型別來生成相應的SQL語句。
  • Django支援MySQL5.5及更高版本。

Django ORM 常用欄位和引數

常用欄位

AutoField

int自增列,必須填入引數 primary_key=True。當model中如果沒有自增列,則自動會建立一個列名為id的列。

IntegerField

一個整數型別,範圍在 -2147483648 to 2147483647。

CharField

字元型別,必須提供max_length引數, max_length表示字元長度。

DateField

日期欄位,日期格式  YYYY-MM-DD,相當於Python中的datetime.date()例項。

DateTimeField

日期時間欄位,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相當於Python中的datetime.datetime()例項。

欄位合集(爭取記憶)

   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):
        - 小整數 -3276832767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整數 032767
    IntegerField(Field)
        - 整數列(有符號的) -21474836482147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整數 02147483647

    BigIntegerField(IntegerField):
        - 長整型(有符號的) -92233720368547758089223372036854775807

    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)
        - 二進位制型別
欄位合集

自定義欄位(瞭解為主)

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):
        super().__init__(max_length=max_length, *args, **kwargs)
        self.length = max_length

    def db_type(self, connection):
        """
        限定生成資料庫表的欄位型別為char,長度為length指定的值
        """
        return 'char(%s)' % self.length


class Class(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=25)
    # 使用上面自定義的char型別的欄位
    cname = FixedCharField(max_length=25)
複製程式碼

建立的表結構:

附ORM欄位與資料庫實際欄位的對應關係

對應關係:
    '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)',
對應關係

欄位引數

null

用於表示某個欄位可以為空。

unique

如果設定為unique=True 則該欄位在此表中必須是唯一的 。

db_index

如果db_index=True 則代表著為此欄位設定資料庫索引。

default

為該欄位設定預設值。

時間欄位獨有

DatetimeField、DateField、TimeField這個三個時間欄位,都可以設定如下屬性。

auto_now_add

配置auto_now_add=True,建立資料記錄的時候會把當前時間新增到資料庫。

auto_now

配置上auto_now=True,每次更新資料記錄的時候會更新該欄位。

 

關係欄位

ForeignKey

外來鍵型別在ORM中用來表示外來鍵關聯關係,一般把ForeignKey欄位設定在 '一對多'中'多'的一方。

ForeignKey可以和其他表做關聯關係同時也可以和自身做關聯關係。

欄位引數

to

設定要關聯的表

to_field

設定要關聯的表的欄位

related_name

反向操作時,使用的欄位名,用於代替原反向查詢時的'表名_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()

related_query_name

反向查詢操作時,使用的連線字首,用於替換表名。

on_delete

當刪除關聯表中的資料時,當前表與其關聯的行的行為。

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)
    )
複製程式碼

db_constraint

是否在資料庫中建立外來鍵約束,預設為True。

OneToOneField

一對一欄位。

通常一對一欄位用來擴充套件已有欄位。

示例

一對一的關聯關係多用在當一張表的不同欄位查詢頻次差距過大的情況下,將本可以儲存在一張表的欄位拆開放置在兩張表中,然後將兩張表建立一對一的關聯關係。

複製程式碼
class Author(models.Model):
    name = models.CharField(max_length=32)
    info = models.OneToOneField(to='AuthorInfo')
    

class AuthorInfo(models.Model):
    phone = models.CharField(max_length=11)
    email = models.EmailField()

 

複製程式碼

欄位引數

to

設定要關聯的表。

to_field

設定要關聯的欄位。

on_delete

同ForeignKey欄位。

ManyToManyField

用於表示多對多的關聯關係。在資料庫中通過第三張表來建立關聯關係。

欄位引數

to

設定要關聯的表

related_name

同ForeignKey欄位。

related_query_name

同ForeignKey欄位。

symmetrical

僅用於多對多自關聯時,指定內部是否建立反向操作的欄位。預設為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屬性進行反向查詢。

through

在使用ManyToManyField欄位時,Django將自動生成一張表來管理多對多的關聯關係。

但我們也可以手動建立第三張表來管理多對多關係,此時就需要通過through來指定第三張表的表名。

through_fields

設定關聯的欄位。

db_table

預設建立第三張表時,資料庫中表的名稱。

多對多關聯關係的三種方式 

方式一:自行建立第三張表

複製程式碼
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="書名")


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")


# 自己建立第三張表,分別通過外來鍵關聯書和作者
class Author2Book(models.Model):
    author = models.ForeignKey(to="Author")
    book = models.ForeignKey(to="Book")

    class Meta:
        unique_together = ("author", "book")
複製程式碼

方式二:通過ManyToManyField自動建立第三張表

複製程式碼
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="書名")


# 通過ORM自帶的ManyToManyField自動建立第三張表
class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")
    books = models.ManyToManyField(to="Book", related_name="authors")
複製程式碼

方式三:設定ManyTomanyField並指定自行建立的第三張表

複製程式碼
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="書名")


# 自己建立第三張表,並通過ManyToManyField指定關聯
class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")
    books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
    # through_fields接受一個2元組('field1','field2'):
    # 其中field1是定義ManyToManyField的模型外來鍵的名(author),field2是關聯目標模型(book)的外來鍵名。


class Author2Book(models.Model):
    author = models.ForeignKey(to="Author")
    book = models.ForeignKey(to="Book")

    class Meta:
        unique_together = ("author", "book")
複製程式碼

 

注意:

當我們需要在第三張關係表中儲存額外的欄位時,就要使用第三種方式。

但是當我們使用第三種方式建立多對多關聯關係時,就無法使用set、add、remove、clear方法來管理多對多的關係了,需要通過第三張表的model來管理多對多關係。

元資訊

ORM對應的類裡面包含另一個Meta類,而Meta類封裝了一些資料庫的資訊。主要欄位如下:

db_table

ORM在資料庫中的表名預設是 app_類名,可以通過db_table可以重寫表名。

index_together

聯合索引。

unique_together

聯合唯一索引。

ordering

指定預設按什麼欄位排序。

只有設定了該屬性,我們查詢到的結果才可以被reverse()。

 

 

Object Relational Mapping(ORM)

ORM介紹

ORM概念

物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。

簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。

ORM在業務邏輯層和資料庫層之間充當了橋樑的作用。

ORM由來

讓我們從O/R開始。字母O起源於"物件"(Object),而R則來自於"關係"(Relational)。

幾乎所有的軟體開發過程中都會涉及到物件和關係資料庫。在使用者層面和業務邏輯層面,我們是面向物件的。當物件的資訊發生變化的時候,我們就需要把物件的資訊儲存在關係資料庫中。

按照之前的方式來進行開發就會出現程式設計師會在自己的業務邏輯程式碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關資料,而這些程式碼通常都是重複的。

ORM的優勢

ORM解決的主要問題是物件和關係的對映。它通常把一個類和一個表一一對應,類的每個例項對應表中的一條記錄,類的每個屬性對應表中的每個欄位。 

ORM提供了對資料庫的對映,不用直接編寫SQL程式碼,只需像操作物件一樣從資料庫操作資料。

讓軟體開發人員專注於業務邏輯的處理,提高了開發效率。

ORM的劣勢

ORM的缺點是會在一定程度上犧牲程式的執行效率。

ORM用多了SQL語句就不會寫了,關係資料庫相關技能退化...

ORM總結

ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不可否認的。

但我們不能指望某個工具能一勞永逸地解決所有問題,一些特殊問題還是需要特殊處理的。

但是在整個軟體開發過程中需要特殊處理的情況應該都是很少的,否則所謂的工具也就失去了它存在的意義。

Django中的ORM

Django專案使用MySQL資料庫

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

Model

在Django中model是你資料的單一、明確的資訊來源。它包含了你儲存的資料的重要欄位和行為。通常,一個模型(model)對映到一個數據庫表,

基本情況:

  • 每個模型都是一個Python類,它是django.db.models.Model的子類。
  • 模型的每個屬性都代表一個數據庫欄位。
  • 綜上所述,Django為您提供了一個自動生成的資料庫訪問API,詳詢官方文件連結

 

快速入門 

下面這個例子定義了一個 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
);

一些說明:

  • 表myapp_person的名稱是自動生成的,如果你要自定義表名,需要在model的Meta類中指定 db_table 引數,強烈建議使用小寫表名,特別是使用MySQL作為後端資料庫時。
  • id欄位是自動新增的,如果你想要指定自定義主鍵,只需在其中一個欄位中指定 primary_key=True 即可。如果Django發現你已經明確地設定了Field.primary_key,它將不會新增自動ID列。
  • 本示例中的CREATE TABLE SQL使用PostgreSQL語法進行格式化,但值得注意的是,Django會根據配置檔案中指定的資料庫後端型別來生成相應的SQL語句。
  • Django支援MySQL5.5及更高版本。

Django ORM 常用欄位和引數

常用欄位

AutoField

int自增列,必須填入引數 primary_key=True。當model中如果沒有自增列,則自動會建立一個列名為id的列。

IntegerField

一個整數型別,範圍在 -2147483648 to 2147483647。

CharField

字元型別,必須提供max_length引數, max_length表示字元長度。

DateField

日期欄位,日期格式  YYYY-MM-DD,相當於Python中的datetime.date()例項。

DateTimeField

日期時間欄位,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相當於Python中的datetime.datetime()例項。

欄位合集(爭取記憶)

   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):
        - 小整數 -3276832767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整數 032767
    IntegerField(Field)
        - 整數列(有符號的) -21474836482147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整數 02147483647

    BigIntegerField(IntegerField):
        - 長整型(有符號的) -92233720368547758089223372036854775807

    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)
        - 二進位制型別
欄位合集

自定義欄位(瞭解為主)

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):
        super().__init__(max_length=max_length, *args, **kwargs)
        self.length = max_length

    def db_type(self, connection):
        """
        限定生成資料庫表的欄位型別為char,長度為length指定的值
        """
        return 'char(%s)' % self.length


class Class(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=25)
    # 使用上面自定義的char型別的欄位
    cname = FixedCharField(max_length=25)
複製程式碼

建立的表結構:

附ORM欄位與資料庫實際欄位的對應關係

對應關係:
    '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)',
對應關係

欄位引數

null

用於表示某個欄位可以為空。

unique

如果設定為unique=True 則該欄位在此表中必須是唯一的 。

db_index

如果db_index=True 則代表著為此欄位設定資料庫索引。

default

為該欄位設定預設值。

時間欄位獨有

DatetimeField、DateField、TimeField這個三個時間欄位,都可以設定如下屬性。

auto_now_add

配置auto_now_add=True,建立資料記錄的時候會把當前時間新增到資料庫。

auto_now

配置上auto_now=True,每次更新資料記錄的時候會更新該欄位。

 

關係欄位

ForeignKey

外來鍵型別在ORM中用來表示外來鍵關聯關係,一般把ForeignKey欄位設定在 '一對多'中'多'的一方。

ForeignKey可以和其他表做關聯關係同時也可以和自身做關聯關係。

欄位引數

to

設定要關聯的表

to_field

設定要關聯的表的欄位

related_name

反向操作時,使用的欄位名,用於代替原反向查詢時的'表名_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()

related_query_name

反向查詢操作時,使用的連線字首,用於替換表名。

on_delete

當刪除關聯表中的資料時,當前表與其關聯的行的行為。

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)
    )
複製程式碼

db_constraint

是否在資料庫中建立外來鍵約束,預設為True。

OneToOneField

一對一欄位。

通常一對一欄位用來擴充套件已有欄位。

示例

一對一的關聯關係多用在當一張表的不同欄位查詢頻次差距過大的情況下,將本可以儲存在一張表的欄位拆開放置在兩張表中,然後將兩張表建立一對一的關聯關係。

複製程式碼
class Author(models.Model):
    name = models.CharField(max_length=32)
    info = models.OneToOneField(to='AuthorInfo')
    

class AuthorInfo(models.Model):
    phone = models.CharField(max_length=11)
    email = models.EmailField()

 

複製程式碼

欄位引數

to

設定要關聯的表。

to_field

設定要關聯的欄位。

on_delete

同ForeignKey欄位。

ManyToManyField

用於表示多對多的關聯關係。在資料庫中通過第三張表來建立關聯關係。

欄位引數

to

設定要關聯的表

related_name

同ForeignKey欄位。

related_query_name

同ForeignKey欄位。

symmetrical

僅用於多對多自關聯時,指定內部是否建立反向操作的欄位。預設為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屬性進行反向查詢。

through

在使用ManyToManyField欄位時,Django將自動生成一張表來管理多對多的關聯關係。

但我們也可以手動建立第三張表來管理多對多關係,此時就需要通過through來指定第三張表的表名。

through_fields

設定關聯的欄位。

db_table

預設建立第三張表時,資料庫中表的名稱。

多對多關聯關係的三種方式 

方式一:自行建立第三張表

複製程式碼
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="書名")


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="作者姓名")


# 自己建立第三張表,分別通過外來鍵關聯書和作者
class Author2Book(models.Model):
    author = models.ForeignKey(to="Author")
    book = models.ForeignKey(to="Book")

    class Meta:
        unique_together = ("author", "book")

相關推薦

python—day59 Object Relational Mapping(ORM)

不可 所有 sql語法 nothing 關系數據庫 sca docs eth mst Object Relational Mapping(ORM) ORM介紹 ORM概念 對象關系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向對

Object Relational Mapping(ORM)

    Object Relational Mapping(ORM) ORM介紹 ORM概念 物件關

ORMObject Relational Mapping

ORM的簡紹 物件關係對映(英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程式技術,用於實現面向物件程式語言裡不同型別系統的資料之間的轉換 。從效果上說,它其實是建立了一個可在程式語言裡使用的--"虛擬物件資料庫"。 面向物

Object/Relational Mapping 數學關系 反面向對象

自己 des framework index.php ati ans psu process 成功 【hibernate ORM 是對象關系映射框架 事實上的持久化存儲引擎】 http://docs.jboss.org/hibernate/orm/5.2/userguid

Object Relational Mapping

AutoField(Field) - int自增列,必須填入引數 primary_key=True BigAutoField(AutoField) - bigint自增列,必須填入引數 primary_key=True

ORMobject relationship mapping

distinct tinc 關聯 記錄操作 log book pytho exist filter ORM: object relationship mapping 關於數據庫的兩條命令: python manage.py makemigrations pyth

ORM--Object/Relation Mapping 對象關系映射

img 分享圖片 mage 圖片 -- image com png object ORM--Object/Relation Mapping 對象關系映射

rest-assured的對象映射(Object Mapping)

numbers 自定義 inner 簡單的 onf 我們 last bsp 方式 rest-assured支持映射Java對象到Json和XML以及從Json和XML中映射到Java對象。Json映射需要在classpath 中有Jackson、Jackson 2或者是Gs

ORM多表操作(object與queryset)

ORM多表操作 一、建立模型 作者模型:一個作者有姓名和年齡。 作者詳細模型:把作者的詳情放到詳情表,包含生日,手機號,家庭住址等資訊;作者詳情模型和作者模型之間是一對一的關係。 出版商模型:出版商有名稱,所在城市以及郵箱。 書籍模型: 書籍有書名和出版日期,一本書可能會有多個作者,一個作者也可以寫

elasticsearch核心知識---49.ES中mapping root object _source _all _store _index關鍵字理解

關於_source  _all   _store  _index 這四個關鍵字  在這篇文章中非常詳細點選開啟連結1.root object就是某個type對應的mapping json,包括了properties,metadata(_id,_source,_type),se

Django ORM queryset object 解釋(子查詢和join連表查詢的結果)

解釋 pri mod span books round 取數據 通過 color #下面兩種是基於QuerySet查詢 也就是說SQL中用的jion連表的方式查詢books = models.UserInfo.objects.all() print(type(books)

[Django] 查看orm自己主動運行的原始查詢sql

ice 微軟 bug sof execute 通過 nec cut ren django的文檔看了非常多。也用了不少,有的時候感覺性能非常不好,知道非常多地方是惰性查詢。可是對於復雜的邏輯。僅僅是表面上發現執行非常慢,機器資源消耗非常多。卻不知道orm究竟是什麽來轉化成

C#如何對List中的Object進行排序

過多 code same ascend 多個 delegate del object compareto 首先定義一個List類,這個類裏面包含了Name和Total兩個屬性變量,下面就是針對這兩個變量進行排序。 public class Player { pub

Vue的報錯:Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

pac rop space efault type require bject default logs 剛剛運行一下以前的一個Vue+webpack的demo,運行之後沒有出現想象中的效果,並且報錯 Uncaught TypeError: Cannot assign t

(一)ORM基礎

帶來 腳本 ace java hibernate com 數據庫 交互 操作 一、ORM思想解析   要了解學習Hibernate框架,就不得不提到ORM思想,因為Hibernate就是基於ORM思想的一個產品。   1.1  介紹 廣義上,ORM指的是面向對象的對象

elasticsearch index 之 Mapping

splay ima 更多 trie name .post 結構 emp parser Lucene索引的一個特點就filed,索引以field組合。這一特點為索引和搜索提供了很大的靈活性。elasticsearch則在Lucene的基礎上更近一步,它可以是 no schem

css3圖片處理方式 object-fit

含義 class 替換 down 區域 尺寸 屬性 obj over .fill { object-fit: fill; } .contain { object-fit: contain; } .cover { object-fit: cover; } .none { o

深入研究java.lang.Object

下一個 line 版本號 gin bool 獲得 不同 ava 表達 前言:Java的類庫日益龐大。所包括的類和接口也不計其數。但當中有一些非常重要的類和接口,是Java類庫中的核心部分。常見的有String、Object、Class、Collection、Class

Morphia - mongodb之ORM框架

embedded art tails transient sdn tar detail nbsp hit 一、簡介 二、註解 [email protected]/* */ [email protected]/* */[email prote

Object-C iOS純代碼布局 一堆代碼可以放這裏!

objective 是我 cti blog 今天 object 1-1 擴展 類的屬性 前言: 最近寫的文章都是創業類,好吧,今天好好寫寫技術類的文章! 不過分享的不是IOS相關的文章,畢竟這幾天在速成IOS,看的是objective-c,由於速成的很快,好累! 好在