2016-07-20 21 views
2

我正在使用Django和REST框架來構建將數據提供給AngularJS網站的API。我需要確保所有驗證都在後端完成。Django在空白CharFields上引發異常

我有一個型號命名爲候選人:

class Candidate(CreatedModel): 

    first_name = CharField(max_length=30) 
    last_name = CharField(max_length=100) 
    email = CharField(max_length=254, unique=True) 
    phone = CharField(max_length=20, null=True) 
    resume_path = CharField(max_length=200, null=True) 
    notes = TextField(null=True) 

在這個模型中,只有first_namelast_nameemail是必需的。其餘的字段可以爲空。

然後我運行服務器併發出測試POST請求來創建一個新的候選人。問題是,即使我沒有指定任何字段,它只會給他們所有空字符串值("")。

我聽說Django Model Fields的blank屬性,但它只適用於表單驗證而不適用於HTTP請求。

現在看來我可以解決這個問題的唯一方法是覆蓋BaseModel類上的save()函數,並檢查所有CharFields是否已填充或引發錯誤。

想法?提前致謝!

+0

如果你使用的是drf,你可以在序列化中使用校驗器:http://www.django-rest-framework.org/api-guide/validators/#optional-fields – jape

+0

我想你會快100倍如果你使用Python EVE,如果你正在構建一個REST API! –

+1

@jape謝謝!我會看看驗證器! –

回答

1

爲什麼會發生在此說明:在使用基於字符串的領域,如CharField和 文本字段爲空https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.Field.null

避免因空字符串值總是會被​​存儲爲空 字符串,而不是爲NULL。如果基於字符串的字段的值爲空= True,那麼 表示它有兩個可能的「無數據」值:NULL和空字符串 。在大多數情況下, 「沒有數據」有兩個可能的值是多餘的,Django慣例是使用空字符串,而不是NULL。

如果您不希望空字符串在您的數據庫中,您可以簡單地在您的表單中將該字段標記爲required。或者使用DRF validators

+0

感謝您的回覆!我會考慮改變空字符串值的策略。我不能使用'required',因爲我沒有使用Django表單。儘管如此,DRF驗證器將會有所幫助。 –

+0

很高興得到了幫助 – e4c5

2

經過一番研究,我發現了一種避免將空字符串保存在我的數據庫中的方法。我創建了一個名爲NonBlankCharField的定製Django Field,它繼承CharField並覆蓋empty_strings_allowed

class NonBlankCharField(CharField): 
    empty_strings_allowed = False 

然後我用這個Field代替CharField。當未指定不應該爲NULLField時,這將引起IntegrityException

如果你看一下Django的源代碼(型號/ fields.py文件裏),它表明:

def get_default(self): 
    """ 
    Returns the default value for this field. 
    """ 
    if self.has_default(): 
     if callable(self.default): 
      return self.default() 
     return self.default 
    if (not self.empty_strings_allowed or (self.null and 
       not connection.features.interprets_empty_strings_as_nulls)): 
     return None 
    return "" 

這是怎麼Field獲得它的缺省值。 empty_strings_allowed設置爲True默認爲CharField,因此這將覆蓋該值,並使Field保存爲None,然後提高Exception

但是,其他答案建議使用DRF驗證程序,這可能是侵入性較弱的,所以我會在我的解決方案上做到這一點。

謝謝大家的幫助。