1. 程式人生 > 實用技巧 >Django-模型-欄位類

Django-模型-欄位類

欄位類做什麼?

  • 當你想要一個自定義欄位時,你最終會建立兩個類:

    • 第一類是使用者將操作的Python物件。他們將它分配給模型屬性,他們將從它讀取用於顯示的目的
    • 第二個類是Field子類。這是知道如何在其永久儲存形式和Python表單之間來回轉換你的第一個類的類。

寫一個欄位子類  

  • 新欄位與之最相似的現有Field類。你可以繼承一個現有的Django欄位並儲存自己一些工作嗎?如果沒有,你應該繼承Field類,所有類都從中繼承。
  • 初始化您的新欄位是一個問題,從您的案例中分離出任何特定於常見引數的引數,並將後者傳遞到Field__init__()
    from django.db import
    models class HandField(models.Field): description = "A hand of cards (bridge style)" def __init__(self, *args, **kwargs): kwargs['max_length'] = 104 super(HandField, self).__init__(*args, **kwargs)

  • Field.__init__()方法採用以下引數:
    verbose_name 名稱
    primary_key(關鍵字)
    max_length(最大長度)
    unique(唯一性)
    blank(空白)
    null(空值)
    db_index(資料庫(建立)索引)
    rel:用於相關欄位(如ForeignKey)。 僅供高階使用。
    default(預設值)
    editable(可編輯)
    serialize:如果False,當模型傳遞給Django的serializers時,欄位不會被序列化。 預設為True。
    unique_for_date
    unique_for_month
    unique_for_year
    choices(選擇)
    help_text
    db_column
    db_tablespace:僅用於建立索引(如果後端支援tablespaces)。 您通常可以忽略此選項。
    auto_created:True如果自動建立欄位,就像模型繼承使用的OneToOneField。 僅供高階使用。

欄位解構

  • 寫入__init__()方法的目的是寫入deconstruct()方法。這個方法告訴Django如何獲取一個新欄位的例項,並將其減少為序列化形式 - 特別是要傳遞給__init__()的引數以重新建立它。
  • deconstruct()的契約很簡單;它返回一個四項的元組:欄位的屬性名稱,欄位類的完整匯入路徑,位置引數(作為列表)和關鍵字引數(作為dict)。注意,這不同於自定義類的deconstruct()方法for custom classes
  • 作為自定義領域的作者,前兩個值不用關心;你必須關心位置和關鍵字引數,因為這些可能是你正在改變的事情。
  • 例如,在我們的HandField
    類中,我們總是強制在__init__()中設定max_length。基礎Field類的deconstruct()方法將看到這一點,並嘗試將其返回到關鍵字引數中;因此,我們可以從關鍵字引數中刪除它,以便可讀性:
from django.db import models

class HandField(models.Field):

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 104
        super(HandField, self).__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super(HandField, self).deconstruct()
        del kwargs["max_length"]
        return name, path, args, kwargs
  • 如果您添加了一個新的關鍵字引數,則需要編寫程式碼以將其值自動新增到kwargs中:
    from django.db import models
    
    class CommaSepField(models.Field):
        "Implements comma-separated storage of lists"
    
        def __init__(self, separator=",", *args, **kwargs):
            self.separator = separator
            super(CommaSepField, self).__init__(*args, **kwargs)
    
        def deconstruct(self):
            name, path, args, kwargs = super(CommaSepField, self).deconstruct()
            # Only include kwarg if it's not the default
            if self.separator != ",":
                kwargs['separator'] = self.separator
            return name, path, args, kwargs