1. 程式人生 > >欄位的引數 -- Django從入門到精通系列教程

欄位的引數 -- Django從入門到精通系列教程

該系列教程繫個人原創,並完整發布在個人官網劉江的部落格和教程

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

所有的模型欄位都可以接收一定數量的引數,比如CharField至少需要一個max_length引數。下面的這些引數是所有欄位都可以使用的,並且是可選的。

null

該值為True時,Django在資料庫用NULL儲存空值。預設值為False。對於儲存字串型別資料的欄位,請儘量避免將此引數設為True,那樣會導致兩種‘沒有資料’的情況,一種是NULL,另一種是‘空字串’。

blank

True時,欄位可以為空。預設False。和null引數不同的是,null是純資料庫層面的,而blank是驗證相關的,它與表單驗證是否允許輸入框內為空有關,與資料庫無關。所以要小心一個null為False,blank為True的欄位接收到一個空值可能會出bug或異常。

choices

用於頁面上的選擇框標籤,需要先提供一個二維的二元元組,第一個元素表示存在資料庫內真實的值,第二個表示頁面上顯示的具體內容。在瀏覽器頁面上將顯示第二個元素的值。例如:

    YEAR_IN_SCHOOL_CHOICES = (
        ('FR', 'Freshman'),
        ('SO', 'Sophomore'),
        ('JR', 'Junior'),
        ('SR', 'Senior'),
        ('GR', 'Graduate'),
    )

一般來說,最好將選項定義在類裡,並取一個直觀的名字,如下所示:

from django.db import models

class Student(models.Model):
    FRESHMAN = 'FR'
    SOPHOMORE = 'SO'
    JUNIOR = 'JR'
    SENIOR = 'SR'
    YEAR_IN_SCHOOL_CHOICES = (
        (FRESHMAN, 'Freshman'),
        (SOPHOMORE, 'Sophomore'),
        (JUNIOR, 'Junior'),
        (SENIOR, 'Senior'),
    )
    year_in_school = models.CharField(
        max_length=2,
        choices=YEAR_IN_SCHOOL_CHOICES,
        default=FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in (self.JUNIOR, self.SENIOR)

要獲取一個choices的第二元素的值,可以使用get_FOO_display()方法,其中的FOO用欄位名代替。對於下面的例子:

from django.db import models

class Person(models.Model):
    SHIRT_SIZES = (
    ('S', 'Small'),
    ('M', 'Medium'),
    ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

使用方法:

>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'

db_column

該引數用於定義當前欄位在資料表內的列名。如果未指定,Django將使用欄位名作為列名。

db_index

該引數接收布林值。如果為True,資料庫將為該欄位建立索引。

db_tablespace

用於欄位索引的資料庫表空間的名字,前提是當前欄位設定了索引。預設值為工程的DEFAULT_INDEX_TABLESPACE設定。如果使用的資料庫不支援表空間,該引數會被忽略。

default

欄位的預設值,可以是值或者一個可呼叫物件。如果是可呼叫物件,那麼每次建立新物件時都會呼叫。設定的預設值不能是一個可變物件,比如列表、集合等等。lambda匿名函式也不可用於default的呼叫物件,因為匿名函式不能被migrations序列化。

注意:在某種原因不明的情況下將default設定為None,可能會引發intergyerror:not null constraint failed,即非空約束失敗異常,導致python manage.py migrate失敗,此時可將None改為False或其它的值,只要不是None就行。

editable

如果設為False,那麼當前欄位將不會在admin後臺或者其它的ModelForm表單中顯示,同時還會被模型驗證功能跳過。引數預設值為True。

error_messages

用於自定義錯誤資訊。引數接收字典型別的值。字典的鍵可以是nullblankinvalidinvalid_choiceuniqueunique_for_date其中的一個。

help_text

額外顯示在表單部件上的幫助文字。使用時請注意轉義為純文字,防止指令碼攻擊。

primary_key

如果你沒有給模型的任何欄位設定這個引數為True,Django將自動建立一個AutoField自增欄位,名為‘id’,並設定為主鍵。也就是id = models.AutoField(primary_key=True)

如果你為某個欄位設定了primary_key=True,則當前欄位變為主鍵,並關閉Django自動生成id主鍵的功能。

primary_key=True隱含null=Falseunique=True的意思。一個模型中只能有一個主鍵欄位!

另外,主鍵欄位不可修改,如果你給某個物件的主鍵賦個新值實際上是建立一個新物件,並不會修改原來的物件。

from django.db import models
class Fruit(models.Model):
    name = models.CharField(max_length=100, primary_key=True)
###############    
>>> fruit = Fruit.objects.create(name='Apple')
>>> fruit.name = 'Pear'
>>> fruit.save()
>>> Fruit.objects.values_list('name', flat=True)
['Apple', 'Pear']

unique

設為True時,在整個資料表內該欄位的資料不可重複。

注意:對於ManyToManyField和OneToOneField關係型別,該引數無效。

注意: 當unique=True時,db_index引數無須設定,因為unqiue隱含了索引。

注意:自1.11版本後,unique引數可以用於FileField欄位。

unique_for_date

日期唯一。可能不太好理解。舉個栗子,如果你有一個名叫title的欄位,並設定了引數unique_for_date="pub_date",那麼Django將不允許有兩個模型物件具備同樣的title和pub_date。有點類似聯合約束。

unique_for_month

同上,只是月份唯一。

unique_for_year

同上,只是年份唯一。

verbose_name

為欄位設定一個人類可讀,更加直觀的別名。

對於每一個欄位型別,除了ForeignKeyManyToManyFieldOneToOneField這三個特殊的關係型別,其第一可選位置引數都是verbose_name。如果沒指定這個引數,Django會利用欄位的屬性名自動建立它,並將下劃線轉換為空格。

下面這個例子的verbose name是"person’s first name":

first_name = models.CharField("person's first name", max_length=30)

下面這個例子的verbose name是"first name":

first_name = models.CharField(max_length=30)

對於外來鍵、多對多和一對一字欄位,由於第一個引數需要用來指定關聯的模型,因此必須用關鍵字引數verbose_name來明確指定。如下:

poll = models.ForeignKey(
    Poll,
    on_delete=models.CASCADE,
    verbose_name="the related poll",
    )
sites = models.ManyToManyField(Site, verbose_name="list of sites")
    place = models.OneToOneField(
    Place,
    on_delete=models.CASCADE,
    verbose_name="related place",
)

另外,你無須大寫verbose_name的首字母,Django自動為你完成這一工作。

validators

執行在該欄位上的驗證器的列表。