簡體   English   中英

根據另一個字段的值驗證 Django 模型字段?

[英]Validating a Django model field based on another field's value?

我有一個 Django 應用程序,其模型可通過 Django REST 框架和常規表單界面訪問。 表單界面在保存對模型的更改之前有一些驗證檢查,但不使用任何特殊的 Django 框架,只是在視圖中進行簡單的本地更改。

我想對表單和 REST 調用應用相同的驗證,所以我想將我的驗證移到模型中。 我可以看到如何使用 Field 的驗證器字段在簡單情況下執行此操作,但在一種情況下,我有一個名稱/類型/值模型,其中“值”的可接受值根據選擇的類型而變化。 驗證器不會收到有關該字段所在模型的任何信息,因此它無權訪問其他字段。

如何在 DRF 的序列化程序和表單的 POST 視圖中沒有本質上相同的代碼的情況下執行此驗證?

我稍微挖掘了一下 drf 的代碼庫。 您可以使用以下方法獲取所有字段的值,但文檔中未提及。 這樣做,您可以將序列化錯誤作為{'my_field':'error message}而不是{'non_field_error':'error message'}

def validate_myfield(self, value):
   data = self.get_initial() # data for all the fields
   #do your validation

但是,如果您希望為 ListSerializer 執行此操作,即對於serializer = serializer_class(many=True) ,這將不起作用。 您將獲得空值列表。 在這種情況下,您可以在def validate函數中編寫驗證並避免序列化錯誤中的non_field_errors ,您可以使用錯誤消息作為字典而不是字符串來引發ValidationError

def validate(self, data):
    # do your validation
    raise serializers.ValidationError({"your_field": "error_message"})
 

當按如下方式定義時,每個字段的驗證不會發送有關其他字段的任何信息:

def validate_myfield(self, value):
    ...

但是,如果您有這樣定義的方法:

def validate(self, data):
    ...

然后你在一個字典中得到所有的數據,你就可以做跨領域的驗證了。

您可以使用所需的包進行跨領域驗證。 它允許您在 python 中聲明性地表達您的驗證規則。 使用 DRF 你會有這樣的事情:

class MySerializer(serializers.Serializer):

    REQUIREMENTS = (
        Requires("end_date", "start_date") +
        Requires("end_date", R("end_date") > R("start_date")) + 
        Requires("end_date", R("end_date") < today.date() + one_year) + 
        Requires("start_date", R("start_date") < today.date() + one_year)
     )

    start_date = serializers.DateField(required=False, null=True, blank=True)
    end_date = serializers.DateField(required=False, null=True, blank=True)

    def validate(self, data):
        self.REQUIREMENTS.validate(data)  # handle validation error

您可以將REQUIREMENTS放在您的模型上,並讓您的 DRF 和 Django 表單使用它來驗證您的數據。

是一篇解釋更多的博客文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM