二、【用django2.0來(lái)開(kāi)發(fā)】后臺(tái)會(huì)員管理(一) 模型創(chuàng)建與數(shù)據(jù)遷移

這一篇主要是介紹django的模型如何創(chuàng)建, 模型的一些參數(shù), 以及數(shù)據(jù)如何遷移

項(xiàng)目地址

創(chuàng)建會(huì)員模塊

首先我們先創(chuàng)建一個(gè)會(huì)員模塊

> cd cms
> python manager.py account

這樣就在根目錄下創(chuàng)建了一個(gè)account文件夾

創(chuàng)建一個(gè)會(huì)員模型

關(guān)于數(shù)據(jù)庫(kù)的表模型代碼需要寫(xiě)在models.py文件中
account/models.py中的文件代碼


image.png

最終生成的數(shù)據(jù)表的名稱(chēng)為模塊名_類(lèi)名
模型中基本分為三塊

  1. 聲明的字段信息
  2. 模型的元類(lèi), 包含模型的一些配置信息
  3. 模型的其他方法

模型的字段

模型不僅會(huì)影響到數(shù)據(jù)庫(kù)表的創(chuàng)建, 而且會(huì)影響到后臺(tái)表單的展示

我們只介紹最常用的幾種模型字段和選項(xiàng)說(shuō)明
CharField字段
對(duì)應(yīng)的是數(shù)據(jù)庫(kù)的varchar字段, 保存字符串
對(duì)應(yīng)的表單是input類(lèi)型
max_length 可以指定字符串的長(zhǎng)度, 對(duì)應(yīng)的生成的sql代碼就是varchar(64)

DateField字段
對(duì)應(yīng)數(shù)據(jù)庫(kù)的date字段, 保存年-月-日的信息
對(duì)應(yīng)表單中的日期選擇控件
auto_now_add 是指定在數(shù)據(jù)新增時(shí), 自動(dòng)寫(xiě)入時(shí)間
auto_now 是無(wú)論新增還是更新數(shù)據(jù), 此字段都會(huì)更新為當(dāng)前時(shí)間
auto_now_add和auto_now不可以同時(shí)設(shè)置, 否則會(huì)提示你
account.Account.update_time: (fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one of these options may be present.

DateTimeField字段
同DateField字段, 只不過(guò)是包含日期+時(shí)間

EmailField
對(duì)應(yīng)表單的input, 但是會(huì)添加郵件格式校驗(yàn)
django里是郵件字段, 其實(shí)數(shù)據(jù)庫(kù)是varchar字段, 最終繼承的是CharField字段, 但是可以輔助驗(yàn)證郵件的格式, 所以它也有max_length參數(shù)

IntegerField
數(shù)字字段, 對(duì)應(yīng)數(shù)據(jù)庫(kù)的int(11)類(lèi)型
max_length 指定最大長(zhǎng)度
min_length 指定最小長(zhǎng)度
choice 指定字段的選項(xiàng), 格式是((值, 值說(shuō)明),), 這個(gè)參數(shù)會(huì)影響到后臺(tái)表單的展示、新增和編輯

SmallIntegerField
存儲(chǔ)范圍比較小, 其他同IntegerField

TextField
文本類(lèi)型字段, 對(duì)應(yīng)數(shù)據(jù)庫(kù)的text()

字段的公共參數(shù)

這些參數(shù)基本在所有字段中都可以設(shè)置, 所以單獨(dú)拿出來(lái)介紹一下
null
如果是True, 則可以null值, 默認(rèn)是False, 但是在TextField字段中, 這個(gè)應(yīng)該一直是False, 設(shè)置為T(mén)rue, 數(shù)據(jù)庫(kù)會(huì)報(bào)錯(cuò)

blank
如果是True, 則允許插入空值, 默認(rèn)是False, 這個(gè)插入的是空, 對(duì)應(yīng)字符串是'', 而不是null值

choice
字段的選項(xiàng)值, 設(shè)置這個(gè)參數(shù)后, 后臺(tái)表單就會(huì)變成下拉的格式

db_name
字段名, 如果指定這個(gè), 如果不指定, 采用的是模型類(lèi)屬性的名稱(chēng)小寫(xiě), 設(shè)置了以后, 則使用這個(gè)名稱(chēng)

db_index
設(shè)置為T(mén)rue, 則會(huì)在這個(gè)字段上創(chuàng)建索引

default
設(shè)置字段的默認(rèn)值, 不僅支持普通的數(shù)據(jù)類(lèi)型, 也支持函數(shù)


def contact_default():
    return {"email": "to1@example.com"}

contact_info = JSONField("ContactInfo", default=contact_default)

editable
如果是False, 則不會(huì)展示在后臺(tái)或者任何其他的ModelForm中, 也會(huì)跳過(guò)模型驗(yàn)證, 默認(rèn)是True

error_messages
設(shè)置驗(yàn)證失敗時(shí)的錯(cuò)誤信息

account = account = models.CharField(max_length=64, blank=True,  verbose_name='用戶(hù)名', error_messages={
    'max_length': '最大長(zhǎng)度不可超過(guò)64個(gè)字符'
})

help_text
指定在表單頁(yè)面的幫助說(shuō)明問(wèn)題

primary_key
默認(rèn)是False, 如果沒(méi)有指定字段的這個(gè)參數(shù), 則django會(huì)自動(dòng)添加一個(gè)id字段作為主鍵。
primary_key=True則必然null=False 并且unique=True

unique
如果是True, 則這個(gè)字段必須是唯一的

verbose_name
指定后臺(tái)中列表頁(yè), 新增編輯頁(yè)面顯示的表單字段名稱(chēng)

模型元類(lèi)Meta參數(shù)

django中的元類(lèi)用來(lái)設(shè)置一些指定的操作, 以及后臺(tái)的一些設(shè)置

class Account(models.Model):
    class Meta:
        ordering = ['-id']
        verbose_name = '會(huì)員'
        verbose_name_plural = '會(huì)員管理'

class Meta就是一個(gè)元類(lèi)

app_label
指定此模型所屬的模塊名, 如果更改后, 會(huì)影響到表的名稱(chēng)

base_manager_name
指定模型的基本管理者類(lèi)名稱(chēng)(就按照管理者來(lái)翻譯吧)
先簡(jiǎn)單說(shuō)一下, 我們?cè)谑褂胐jango查詢(xún)的時(shí)候, 都會(huì)執(zhí)行django.objects.
那么為什么要這么麻煩的加一個(gè)objects呢?
其實(shí)objects的作用就是返回了一個(gè)manager類(lèi), 而Model其實(shí)只是模型結(jié)構(gòu)的聲明, Manager類(lèi)才是真正操作數(shù)據(jù)庫(kù)的類(lèi)

db_table
指定數(shù)據(jù)庫(kù)表名

default_manager_name
默認(rèn)管理者的名稱(chēng), 和base_manager_name類(lèi)似, 稍后專(zhuān)門(mén)會(huì)有一篇文章解釋

get_latest_by
排序用的, 只能設(shè)置DateField, DateTimeField, IntegerField. 這個(gè)會(huì)作用于Manager的latest()和earliest()方法

# Latest by ascending order_date.
get_latest_by = "order_date"

# Latest by priority descending, order_date ascending.
get_latest_by = ['-priority', 'order_date']

解釋一下, django中-priority代表倒序, priority代表正序

order
類(lèi)似get_latest_by, 執(zhí)行查詢(xún)時(shí), 會(huì)影響到排序方式order_by這個(gè)方法

indexes
設(shè)置表的索引

from django.db import models

class Customer(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=['last_name', 'first_name']),
            models.Index(fields=['first_name'], name='first_name_idx'),
        ]

fields 指定索引列, name是索引名

unique_together
指定唯一字段

unique_together = ("driver", "restaurant")

在寫(xiě)入數(shù)據(jù)時(shí), driverhe restaurant必須是唯一的

verbose_name
指定一個(gè)表的顯示名稱(chēng), 影響后臺(tái)面包屑導(dǎo)航的顯示名稱(chēng)

verbose_name_plural
影響后臺(tái)列表頁(yè)的顯示名稱(chēng)

以上就把關(guān)于模型常用的參數(shù), 屬性都介紹了, 對(duì)照demo的代碼大家可以理解一下

注冊(cè)模塊

執(zhí)行數(shù)據(jù)遷移之前, 先要將模塊注冊(cè)到項(xiàng)目中, 因?yàn)閐jango的模塊設(shè)計(jì)是可插拔的, 減少耦合性

# cms/settings.py
INSTALLED_APPS = [
    'django.contrib.admin', 
    'django.contrib.auth',
    'django.contrib.contenttypes', 'django.contrib.sessions',
    'django.contrib.messages', 'django.contrib.staticfiles',
    'account' # 將模塊名寫(xiě)入list中就完成了注冊(cè)
]

如果不執(zhí)行注冊(cè), 那么項(xiàng)目就不會(huì)加載這個(gè)模塊, 也無(wú)法執(zhí)行數(shù)據(jù)遷移、模塊訪問(wèn), 包括后臺(tái)的操作了

同步模型到數(shù)據(jù)庫(kù)(數(shù)據(jù)遷移)

創(chuàng)建遷移文件

> cd cms
> python manager.py makemigrations

會(huì)提示

Migrations for 'account':
  account/migrations/0001_initial.py
    - Create model Account

打開(kāi)account/migrations/0001_initial.py文件
可以看到我們聲明的Model已經(jīng)轉(zhuǎn)換為了遷移文件, 到這一步其實(shí)還沒(méi)有將模型同步到數(shù)據(jù)庫(kù)

查看遷移狀態(tài)以及遷移執(zhí)行的sql

python manager.py showmigrations account
account
    [ ] 0001_initial

說(shuō)明0001_initial還未遷移, 如果遷移完成則會(huì)變成[x]0001_initial

接下來(lái)我們查看一下執(zhí)行遷移會(huì)出發(fā)的sql

python manage.py sqlmigrate account 0001_initial
BEGIN;
--
-- Create model Account
--
CREATE TABLE `account_account` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `account` varchar(200) NOT NULL UNIQUE, `password` varchar(32) NOT NULL, `email` varchar(32) NOT NULL, `phone` varchar(11) NOT NULL, `status` integer NOT NULL, `create_time` datetime(6) NOT NULL, `update_time` datetime(6) NOT NULL);
COMMIT;

不同的數(shù)據(jù)庫(kù)返回的sql可能是不同的

執(zhí)行遷移

python manager.py migrate

返回

Operations to perform:
  Apply all migrations: account, admin, article, auth, contenttypes, sessions
Running migrations:
  Applying account.0001_initial... OK

則說(shuō)明遷移成功, 打開(kāi)mysql管理工具就可以看到我們創(chuàng)建的account_account這個(gè)表了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,315評(píng)論 2 89
  • 1 創(chuàng)建一個(gè)博客應(yīng)用 在本書(shū)中,你將學(xué)習(xí)如何創(chuàng)建完整的,可用于生產(chǎn)環(huán)境的Django項(xiàng)目。如果你還沒(méi)有安裝Djan...
    lakerszhy閱讀 2,858評(píng)論 9 22
  • 4 創(chuàng)建一個(gè)社交網(wǎng)站 在上一章中,你學(xué)習(xí)了如何創(chuàng)建站點(diǎn)地圖和訂閱,并且為博客應(yīng)用構(gòu)建了一個(gè)搜索引擎。在這一章中,你...
    lakerszhy閱讀 2,266評(píng)論 0 7
  • 可愛(ài) 美味 好吃
    蛋糕城堡閱讀 213評(píng)論 0 0
  • 我擁有弄風(fēng)的竹墻 我要送你花惹皺的衣裳 一院子蝴蝶的夢(mèng) 一箱子沒(méi)數(shù)的羊 我擁有星斗的河床 我要送你光咬過(guò)的水漾 一...
    仙女婷兒_閱讀 679評(píng)論 4 1

友情鏈接更多精彩內(nèi)容