![](/img/trans.png)
[英]Django model limit choices based on another model but with a specific field value
[英]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.