模型的元數據Meta -- Django從入門到精通系列教程

来源:https://www.cnblogs.com/feixuelove1009/archive/2018/02/05/8419493.html
-Advertisement-
Play Games

該系列教程系個人原創,並完整發佈在個人官網 "劉江的博客和教程" 所有轉載本文者,需在頂部顯著位置註明原作者及www.liujiangblog.com官網地址。 Python及Django學習QQ群:453131687 模型的元數據,指的是“除了欄位外的所有內容”,例如排序方式、資料庫表名、人類可讀 ...


該系列教程系個人原創,並完整發佈在個人官網劉江的博客和教程

所有轉載本文者,需在頂部顯著位置註明原作者及www.liujiangblog.com官網地址。

Python及Django學習QQ群:453131687


模型的元數據,指的是“除了欄位外的所有內容”,例如排序方式、資料庫表名、人類可讀的單數或者複數名等等。所有的這些都是非必須的,甚至元數據本身對模型也是非必須的。但是,我要說但是,有些元數據選項能給予你極大的幫助,在實際使用中具有重要的作用,是實際應用的‘必須’。

想在模型中增加元數據,方法很簡單,在模型類中添加一個子類,名字是固定的Meta,然後在這個Meta類下麵增加各種元數據選項或者說設置項。參考下麵的例子:

from django.db import models

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:         # 註意,是模型的子類,要縮進!
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"

上面的例子中,我們為模型Ox增加了兩個元數據‘ordering’和‘verbose_name_plural’,分別表示排序和複數名,下麵我們會詳細介紹有哪些可用的元數據選項。

強調:每個模型都可以有自己的元數據類,每個元數據類也只對自己所在模型起作用。


abstract

如果abstract=True,那麼模型會被認為是一個抽象模型。抽象模型本身不實際生成資料庫表,而是作為其它模型的父類,被繼承使用。具體內容可以參考Django模型的繼承。


app_label

如果定義了模型的app沒有在INSTALLED_APPS中註冊,則必須通過此元選項聲明它屬於哪個app,例如:

app_label = 'myapp'

base_manager_name

自定義模型的_base_manager管理器的名字。模型管理器是Django為模型提供的API所在。Django1.10新增。


db_table

指定在資料庫中,當前模型生成的數據表的表名。比如:

db_table = 'my_freinds'

友情建議:使用MySQL資料庫時,db_table用小寫英文。


db_tablespace

自定義資料庫表空間的名字。預設值是工程的DEFAULT_TABLESPACE設置。


default_manager_name

自定義模型的_default_manager管理器的名字。Django1.10新增。


預設情況下,從一個模型反向關聯設置有關係欄位的源模型,我們使用<model_name>_set,也就是源模型的名字+下劃線+set

這個元數據選項可以讓你自定義反向關係名,同時也影響反向查詢關係名!看下麵的例子:

from django.db import models

class Foo(models.Model):
    pass

class Bar(models.Model):
    foo = models.ForeignKey(Foo)

    class Meta:
        default_related_name = 'bars'   # 關鍵在這裡

具體的使用差別如下:

>>> bar = Bar.objects.get(pk=1)
>>> # 不能再使用"bar"作為反向查詢的關鍵字了。
>>> Foo.objects.get(bar=bar)
>>> # 而要使用你自己定義的"bars"了。
>>> Foo.objects.get(bars=bar)

get_latest_by

Django管理器給我們提供有latest()和earliest()方法,分別表示獲取最近一個和最前一個數據對象。但是,如何來判斷最近一個和最前面一個呢?也就是根據什麼來排序呢?

get_latest_by元數據選項幫你解決這個問題,它可以指定一個類似 DateFieldDateTimeField或者IntegerField這種可以排序的欄位,作為latest()和earliest()方法的排序依據,從而得出最近一個或最前面一個對象。例如:

get_latest_by = "order_date"

managed

該元數據預設值為True,表示Django將按照既定的規則,管理資料庫表的生命周期。

如果設置為False,將不會針對當前模型創建和刪除資料庫表。在某些場景下,這可能有用,但更多時候,你可以忘記該選項。


order_with_respect_to

這個選項不好理解。其用途是根據指定的欄位進行排序,通常用於關係欄位。看下麵的例子:

from django.db import models

class Question(models.Model):
    text = models.TextField()
    # ...

class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    # ...

    class Meta:
        order_with_respect_to = 'question'

上面在Answer模型中設置了order_with_respect_to = 'question',這樣的話,Django會自動提供兩個API,get_RELATED_order()set_RELATED_order(),其中的RELATED用小寫的模型名代替。假設現在有一個Question對象,它關聯著多個Answer對象,下麵的操作返回包含關聯的Anser對象的主鍵的列表[1,2,3]:

>>> question = Question.objects.get(id=1)
>>> question.get_answer_order()
[1, 2, 3]

我們可以通過set_RELATED_order()方法,指定上面這個列表的順序:

>>> question.set_answer_order([3, 1, 2])

同樣的,關聯的對象也獲得了兩個方法get_next_in_order()get_previous_in_order(),用於通過特定的順序訪問對象,如下所示:

>>> answer = Answer.objects.get(id=2)
>>> answer.get_next_in_order()
<Answer: 3>
>>> answer.get_previous_in_order()
<Answer: 1>

這個元數據的作用......還沒用過,囧。


ordering

最常用的元數據之一了!

用於指定該模型生成的所有對象的排序方式,接收一個欄位名組成的元組或列表。預設按升序排列,如果在欄位名前加上字元“-”則表示按降序排列,如果使用字元問號“?”表示隨機排列。請看下麵的例子:

ordering = ['pub_date']             # 表示按'pub_date'欄位進行升序排列
ordering = ['-pub_date']            # 表示按'pub_date'欄位進行降序排列
ordering = ['-pub_date', 'author']  # 表示先按'pub_date'欄位進行降序排列,再按`author`欄位進行升序排列。

permissions

該元數據用於當創建對象時增加額外的許可權。它接收一個所有元素都是二元元組的列表或元組,每個元素都是(許可權代碼, 直觀的許可權名稱)的格式。比如下麵的例子:

permissions = (("can_deliver_pizzas", "可以送披薩"),)

default_permissions

Django預設給所有的模型設置('add', 'change', 'delete')的許可權,也就是增刪改。你可以自定義這個選項,比如設置為一個空列表,表示你不需要預設的許可權,但是這一操作必須在執行migrate命令之前。


proxy

如果設置了proxy = True,表示使用代理模式的模型繼承方式。具體內容與abstract選項一樣,參考模型繼承章節。


required_db_features

聲明模型依賴的資料庫功能。比如['gis_enabled'],表示模型的建立依賴GIS功能。


required_db_vendor

聲明模型支持的資料庫。Django預設支持sqlite, postgresql, mysql, oracle


select_on_save

決定是否使用1.6版本之前的django.db.models.Model.save()演算法保存對象。預設值為False。這個選項我們通常不用關心。


indexes

Django1.11新增的選項。

接收一個應用在當前模型上的索引列表,如下例所示:

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'),
        ]

unique_together

這個元數據是非常重要的一個!它等同於資料庫的聯合約束!

舉個例子,假設有一張用戶表,保存有用戶的姓名、出生日期、性別和籍貫等等信息。要求是所有的用戶唯一不重覆,可現在有好幾個叫“張偉”的,如何區別它們呢?(不要和我說主鍵唯一,這裡討論的不是這個問題)

我們可以設置不能有兩個用戶在同一個地方同一時刻出生並且都叫“張偉”,使用這種聯合約束,保證資料庫能不能重覆添加用戶(也不要和我談小概率問題)。在Django的模型中,如何實現這種約束呢?

使用unique_together,也就是聯合唯一!

比如:

unique_together = (('name', 'birth_day', 'address'),)

這樣,哪怕有兩個在同一天出生的張偉,但他們的籍貫不同,也就是兩個不同的用戶。一旦三者都相同,則會被Django拒絕創建。這一元數據經常被用在admin後臺,並且強制應用於資料庫層面。

unique_together接收一個二維的元組((xx,xx,xx,...),(),(),()...),每一個元素都是一個元組,表示一組聯合唯一約束,可以同時設置多組約束。為了方便,對於只有一組約束的情況下,可以簡單地使用一維元素,例如:

unique_together = ('name', 'birth_day', 'address')

聯合唯一無法作用於普通的多對多欄位。


index_together

即將廢棄,使用index元數據代替。


verbose_name

最常用的元數據之一!用於設置模型對象的直觀、人類可讀的名稱。可以用中文。例如:

verbose_name = "story"
verbose_name = "披薩"

如果你不指定它,那麼Django會使用小寫的模型名作為預設值。


verbose_name_plural

英語有單數和複數形式。這個就是模型對象的複數名,比如“apples”。因為我們中文通常不區分單複數,所以保持和verbose_name一致也可以。

verbose_name_plural = "stories"
verbose_name_plural = "披薩"

如果不指定該選項,那麼預設的複數名字是verbose_name加上‘s’


label

前面介紹的元數據都是可修改和設置的,但還有兩個只讀的元數據,label就是其中之一。

label等同於app_label.object_name。例如polls.Question,polls是應用名,Question是模型名。


label_lower

同上,不過是小寫的模型名。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2.1語法 public 返回值類型 方法名(){ //方法體 } 2.2方法的調用語法 對象名.方法名 計算平均分和總成績 1 public class Score { 2 /** 3 * 創建類 ScoreCalc 編寫方法實現各功能 編寫測試類 4 * 從鍵盤接收三門課分數,(java c# ...
  • 上一篇介紹了在Web項目中web.xml文件的配置信息,本篇主要介紹裡面非常重要的配置——Servlet配置,重點介紹與Servlet相關的幾個介面和類,包括Servlet介面、ServletConfig介面、ServletContext介面、GenericServlet類、HttpServlet類 ...
  • 匿名函數指一類無須定義標識符的函數或子程式。Python用lambda語法定義匿名函數,只需用表達式而無需申明。lambda語法的定義如下: 有些時候,當我們在傳入函數時,不需要顯式地定義函數,直接傳入匿名函數更方便。匿名函數有個限制,就是只能有一個表達式,無需寫return,返回值就是該表達式的結 ...
  • 前言:認為方法與函數同意義,由於這裡使用method,所以稱為方法 靜態方法: 使用@staticmethod來定義靜態方法。 靜態方法:類和實例都可以調用的方法,實際上跟類沒什麼關係了,對於這種不太相關的就使用靜態方法【用實例和類調用沒有區別】 class Dog(object): def __i... ...
  • 淘寶的頁面大量使用了js載入數據,所以採用selenium來進行爬取更為簡單,selenum作為一個測試工具,主要配合無視窗瀏覽器phantomjs來使用。 ...
  • 花了一個星期,總算把這一道該死的毒瘤題做完了。 這道題有很多種解法,我是用優先隊列+主席樹。 首先每一個區間的和,可以表示為兩個首碼和之差。 我們顯然可以知道,每一次找到的那個最大值必然在以一個點為最後一個點的區間之內。 所以我們可以把每一個點為最後一個點的最大值的區間求出來,先打入隊列。 然後每一 ...
  • 1、簡介 在PHP中這門語言中,因為是弱類型語言,因此使用變數時不需提前定義即可使用。 我們在使用php進行開發的時候,大多數使用雙引號、單引號進行定義字元串。既然有這兩種方式,那麼他們之間肯定是有區別的。 並且,除了單雙引號定義字元串這兩種方式外,php還增加了heredoc和nowdoc這兩種語 ...
  • 1.靜態方法通過@staticmethod裝飾器即可把其裝飾的方法變為一個靜態方法。靜態方法是不可以訪問實例變數或類變數的即沒有self,一個不能訪問實例變數和類變數的方法,其實相當於跟類本身已經沒什麼關係了,它與類唯一的關聯就是需要通過類名來調用這個方法 2.靜態方法的調用 在調用靜態方法的時候, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...