第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Django 入門教程

課程導(dǎo)學(xué)
Django 慕課教程使用指南
Django開發(fā)實戰(zhàn)
35 開發(fā)實戰(zhàn)
首頁 慕課教程 Django 入門教程 Django 入門教程 17 Django 中內(nèi)嵌的 ORM 模型

Django 中內(nèi)嵌的 ORM 模型

本小節(jié)將詳細(xì)為大家介紹 Django 中內(nèi)嵌的 ORM 模型及其使用,這里我會結(jié)合源碼的方式為大家展示 Django 內(nèi)部 ORM 模型的實現(xiàn)原理。

1. ORM 介紹

ORM 的概念如下:

對象關(guān)系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫存在的互不匹配的現(xiàn)象的技術(shù)。

簡單的說,ORM 是通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將程序中的對象自動持久化到關(guān)系數(shù)據(jù)庫中。ORM 在業(yè)務(wù)邏輯層和數(shù)據(jù)庫層之間充當(dāng)了橋梁的作用。ORM 解決的主要問題是對象和關(guān)系的映射。它通常把一個類和一個表一一對應(yīng),類的每個實例對應(yīng)表中的一條記錄,類的每個屬性對應(yīng)表中的每個字段,具體如下圖所示。ORM 提供了對數(shù)據(jù)庫的映射,不用直接編寫 SQL 代碼,只需像操作對象一樣從數(shù)據(jù)庫操作數(shù)據(jù)。讓軟件開發(fā)人員專注于業(yè)務(wù)邏輯的處理,提高了開發(fā)效率。

圖片描述

ORM 模式也是有一定缺點的,它會在一定程度上犧牲程序的執(zhí)行效率。此外,還存在許多復(fù)雜場景是 ORM 模式無法解決的,同樣還是需要手動編寫 SQL 語句完成。

2. Django 內(nèi)嵌的 ORM 模型

2.1 Django 中的模型說明

在 Django 中,一個模型(model)會映射到一個數(shù)據(jù)庫表。每個模型都是一個Python 類,它是django.db.models.Model 的子類,模型的每個屬性都代表一個數(shù)據(jù)庫字段。例如下面的代碼中,我們定義了一個 Member 類。每個 model 會屬于 Django 中的一個應(yīng)用,我們通常會將每個應(yīng)用的 models 寫到該應(yīng)用目錄下的 models.py 中。

# first_django_app/hello_app/models.py

from django.db import models

class Member(models.Model):
    sex_choices = (
        (0, '男'),
        (1, '女'),
    )
    name = models.CharField('姓名', max_length=30)
    age = models.CharField('年齡', max_length=30)
    sex = models.SmallIntegerField('性別', choices=sex_choices, default=0)
    occupation = models.CharField('職業(yè)', max_length=30)
    phone_num = models.CharField('手機號', max_length=14, null=True)
    email = models.EmailField('郵箱', blank=True)
    city = models.CharField('城市', max_length=30)
    register_date = models.DateTimeField('注冊時間', auto_now=True)
    
    def __str__(self):
        return "<%s, %s>" % (self.name, self.phone_num)

    class Meta:
        # 通過db_table自定義數(shù)據(jù)表名
        db_table = 'member'
    

上面模型類的定義中,我們看到幾個和模型相關(guān)的字段類,比如 CharField、SmallIntegerField 等。Django 中定義了許多類似的字段類,這些字段類和數(shù)據(jù)庫中字段的類型是一一映射的。以 MySQL 為例:

# 源碼地址 django/db/backends/mysql/base.py
# ...

class DatabaseWrapper(BaseDatabaseWrapper):
    vendor = 'mysql'
    display_name = 'MySQL'
    # This dictionary maps Field objects to their associated MySQL column
    # types, as strings. Column-type strings can contain format strings; they'll
    # be interpolated against the values of Field.__dict__ before being output.
    # If a column type is set to None, it won't be included in the output.
    data_types = {
        'AutoField': 'integer AUTO_INCREMENT',
        'BigAutoField': 'bigint AUTO_INCREMENT',
        'BinaryField': 'longblob',
        'BooleanField': 'bool',
        'CharField': 'varchar(%(max_length)s)',
        'DateField': 'date',
        'DateTimeField': 'datetime(6)',
        '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(6)',
        'UUIDField': 'char(32)',
    }
    
    # ...
    
# ...

從上面這部分源碼可以看到,Django 中定義的這些字段類都會和 MySQL 中的字段的類型是一一對應(yīng)的。接下來介紹常用的 Field 類型以及相關(guān)的屬性選項。

2.2 Django 中常用的 Field types

在 Django 模型中,每個字段都應(yīng)該是相應(yīng) Field 類的實例,以此決定該表在數(shù)據(jù)庫中保存字段的數(shù)據(jù)類型。在上面的源碼中我們看到 Django 內(nèi)部是定義了25個字段類,其中常用的 Field 類型如下:

  • AutoField:int 自增列,必須填入?yún)?shù) primary_key=True。當(dāng) model 中如果沒有自增列,則自動會創(chuàng)建一個列名為 id 的列;

  • BooleanField:布爾類型 (True/False),這個Field不接受null參數(shù),要想使用可以為 null 的布爾類型的字段,就要使用 NullBooleanField;

  • CharField:最常用的字段類,映射到數(shù)據(jù)庫中會轉(zhuǎn)換成 varchar 類型,使用時必須傳入 max_length 屬性以定義該字符串的最大長度,如果超過254個字符,就不建議使用 CharField 了,此時建議使用 TextField;

  • DateField 和 DateTimeField:都是日期時間的字段類,注意前者只到天,后者可以精確到毫秒。使用這兩個 Field 可以傳遞以下幾個參數(shù):

    • auto_now=True:在每次這個數(shù)據(jù)保存的時候,都使用當(dāng)前的時間;
    • auto_now_add=True:在每條數(shù)據(jù)第一次被添加進去的時候,都使用當(dāng)前的時間;

    此外要注意的是 auto_add_now,auto_now 與 default 是互斥的

  • DecimalField:處理浮點類型的 Field。從上面的源碼可以看到,它有兩個必須填入的參數(shù):

    • max_digits:數(shù)字允許的最大位數(shù);

    • decimal_places:小數(shù)的最大位數(shù);

  • FloatField:也是處理浮點類型的 Field。它和 DecimalField 的區(qū)別就是 Python 中 float 和 decimal 的區(qū)別;

  • IntegerField /BigIntegerField/SmallIntegerField:都是處理整數(shù)類型的 Field;

  • TextField:長文本類型 Field,對應(yīng) MySQL 中的 longtext 類型。

2.3 Django 中的 Field options

每種 Field 類會有一些特定的 Field 選項,比如 CharField 必須要傳入 max_length 屬性值。但是下面這些屬性對于所有 Field 類都是有效的:

  • null:默認(rèn)為 False。如果為 True 則表明在數(shù)據(jù)庫中該字段可以為 null;
  • blank:默認(rèn)為 False。如果為 True 則表明在數(shù)據(jù)庫中該字段可以為不填;
  • choice:設(shè)置可選項,表明該字段的值只能從 choice 中選擇,例如上面 Member 表中定義的 sex 字段,只能為 0 或者 1,代表的含義分別為男或者女;
  • default:設(shè)置字段的默認(rèn)值;
  • help_text:設(shè)置說明信息;
  • primary_key:如果為 True,表明設(shè)置該字段為主鍵。此時 Django 便不會再為我們添加默認(rèn)的 id 主鍵了;
  • unique:設(shè)置該字段的值在表中唯一。

2.4 數(shù)據(jù)庫中生成模型表

接下來,我們需要使用 Django 給我們提供的兩個命令來在數(shù)據(jù)庫中生成 hello_app 應(yīng)用下定義的數(shù)據(jù)模型。注意: Member 類映射的表名默認(rèn)是【應(yīng)用名_類名小寫】,然而在前面的模型代碼中我們通過 model 的 Meta 類中的 db_table 參數(shù)改寫了數(shù)據(jù)庫的具體名稱,所以最后數(shù)據(jù)庫中生成的表名為 member,而不是 hello_app_member。

(django-manual) [root@server first_django_app]# python manage.py makemigrations hello_app
Migrations for 'hello_app':
  hello_app/migrations/0001_initial.py
    - Create model Member
(django-manual) [root@server first_django_app]# python manage.py migrate hello_app
Operations to perform:
  Apply all migrations: hello_app
Running migrations:
  Applying hello_app.0001_initial... OK

執(zhí)行完成后,此時 hello_app 應(yīng)用下的所有 model 就會被映射到 MySQL 數(shù)據(jù)庫中,且會對應(yīng)生成相應(yīng)的模型表(此外還有一個遷移記錄表 django_migrations):

MySQL [django_manual]> show tables;
+-------------------------+
| Tables_in_django_manual |
+-------------------------+
| django_migrations       |
| member                  |
| user                    |
+-------------------------+
3 rows in set (0.00 sec)

我們還可以通過 show create table 表名 命令顯示表的創(chuàng)建語句:

MySQL [django_manual]> show create table member;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                                                                                                                                                                                                                                          |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| member | CREATE TABLE `member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `age` varchar(30) NOT NULL,
  `sex` smallint(6) NOT NULL,
  `occupation` varchar(30) NOT NULL,
  `phone_num` varchar(14) NOT NULL,
  `email` varchar(254) NOT NULL,
  `city` varchar(30) NOT NULL,
  `register_date` datetime(6) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

3. 小結(jié)

本小結(jié)中我們介紹了 ORM 的基本概念,然后講解了 Django 中的 model 相關(guān)知識,介紹了模型層中常見的字段類型和字段選項。最后實戰(zhàn)演示了如何通過 Django 提供的命令在數(shù)據(jù)庫中生成模型層定義的表。接下來我們會在生成的表中使用 Django 給我們提供的 ORM 模型對表進行增刪改查操作。