最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

全部開(kāi)發(fā)者教程

Django 入門教程

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

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

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

1. ORM 介紹

ORM 的概念如下:

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

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

圖片描述

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

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

2.1 Django 中的模型說(shuō)明

在 Django 中,一個(gè)模型(model)會(huì)映射到一個(gè)數(shù)據(jù)庫(kù)表。每個(gè)模型都是一個(gè)Python 類,它是django.db.models.Model 的子類,模型的每個(gè)屬性都代表一個(gè)數(shù)據(jù)庫(kù)字段。例如下面的代碼中,我們定義了一個(gè) Member 類。每個(gè) model 會(huì)屬于 Django 中的一個(gè)應(yīng)用,我們通常會(huì)將每個(gè)應(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('手機(jī)號(hào)', max_length=14, null=True)
    email = models.EmailField('郵箱', blank=True)
    city = models.CharField('城市', max_length=30)
    register_date = models.DateTimeField('注冊(cè)時(shí)間', auto_now=True)
    
    def __str__(self):
        return "<%s, %s>" % (self.name, self.phone_num)

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

上面模型類的定義中,我們看到幾個(gè)和模型相關(guān)的字段類,比如 CharField、SmallIntegerField 等。Django 中定義了許多類似的字段類,這些字段類和數(shù)據(jù)庫(kù)中字段的類型是一一映射的。以 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 中定義的這些字段類都會(huì)和 MySQL 中的字段的類型是一一對(duì)應(yīng)的。接下來(lái)介紹常用的 Field 類型以及相關(guān)的屬性選項(xiàng)。

2.2 Django 中常用的 Field types

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

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

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

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

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

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

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

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

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

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

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

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

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

2.3 Django 中的 Field options

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

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

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

接下來(lái),我們需要使用 Django 給我們提供的兩個(gè)命令來(lái)在數(shù)據(jù)庫(kù)中生成 hello_app 應(yīng)用下定義的數(shù)據(jù)模型。注意: Member 類映射的表名默認(rèn)是【應(yīng)用名_類名小寫】,然而在前面的模型代碼中我們通過(guò) model 的 Meta 類中的 db_table 參數(shù)改寫了數(shù)據(jù)庫(kù)的具體名稱,所以最后數(shù)據(jù)庫(kù)中生成的表名為 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í)行完成后,此時(shí) hello_app 應(yīng)用下的所有 model 就會(huì)被映射到 MySQL 數(shù)據(jù)庫(kù)中,且會(huì)對(duì)應(yīng)生成相應(yīng)的模型表(此外還有一個(gè)遷移記錄表 django_migrations):

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

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

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)知識(shí),介紹了模型層中常見(jiàn)的字段類型和字段選項(xiàng)。最后實(shí)戰(zhàn)演示了如何通過(guò) Django 提供的命令在數(shù)據(jù)庫(kù)中生成模型層定義的表。接下來(lái)我們會(huì)在生成的表中使用 Django 給我們提供的 ORM 模型對(duì)表進(jìn)行增刪改查操作。