嗨!
总结问题
我有一个 Django Rest Framework 后端,我想在其上做一件简单的事情: 更改default validation message:
'max_length': _('Ensure this field has no more than {max_length} characters.'),
自定义一个,例如
'max_length': 'I am happy to see you {max_length}.'
失败的方法在这篇文章的底部
最小示例:
您可以从 git repo 中提取一个最小的示例,并通过调用 this file 来运行测试。
from django.contrib.auth.models import (
AbstractBaseUser,
PermissionsMixin,
)
from django.db import models
from rest_framework import serializers
class User(AbstractBaseUser, PermissionsMixin):
name = models.CharField("Name", max_length=42, null=True,
error_messages={'max_length':"I am happy to see you {max_length}."})
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["name"]
extra_kwargs = {
"name": {"required": True, "allow_blank": False, "allow_null": False},
}
class TestUserSerializer:
def test_name() -> None:
data = {
"name": "A" * 43,
}
serializer = UserSerializer(data=data)
assert serializer.is_valid() is False
assert str(serializer.errors["name"][0]) == "I am happy to see you 42."
错误消息似乎被忽略。
失败的原因:
- ( main )
error_messages
作为 CharField 参数(如示例所示) - ( experiment_1 ) 基于 this issue ,我尝试为 CharField 设置验证参数,例如:
validators=[MaxLengthValidator(42, message="我很高兴见到你 {max_length}。")]
- (实验 2A 2B )基于 very similar stack question 我尝试添加自定义
CharField
类。也许我不理解他们的解决方案,因为从fields.CharField
继承不允许我将内容设置到 init 方法中(我使用model.CharField
,他们使用field. Charfield
。无论如何都不起作用。 - 根据 this issue,我开始怀疑这是否可行。
- ( experiment 3 ) 在
UserSerializer
内编写自定义验证方法def validate_name(self, value):
。它也被忽略。
最佳答案
请随意git am
这个。提交消息中的说明。
还修复了值的显示并添加了测试以确保覆盖在模型级别有效。
From b5e0b90d8aea9348ef0de7624ad1460c06a2c44e Mon Sep 17 00:00:00 2001
From: Melvyn <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3a575f564c43547a494e5b59515f4259525b545d5f1449534e5f" rel="noreferrer noopener nofollow">[email protected]</a>>
Date: Sat, 20 Mar 2021 00:30:29 +0100
Subject: [PATCH] fix(main): Add error_messages to serializer
Apparently the ModelSerializer doesn't copy the error_messages attribute
from the model field, so we have to do that by hand.
---
stack_example/tests/test_user.py | 9 +++++++++
stack_example/user/models.py | 2 +-
stack_example/user/serializers.py | 5 ++---
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/stack_example/tests/test_user.py b/stack_example/tests/test_user.py
index 5aeba74..8493dc1 100644
--- a/stack_example/tests/test_user.py
+++ b/stack_example/tests/test_user.py
@@ -1,5 +1,14 @@
import pytest
from user.serializers import UserSerializer
+from user.models import User
+from django.core.exceptions import ValidationError
+
+def test_model():
+ user = User(name="A" * 43)
+ try:
+ user.clean_fields()
+ except ValidationError as e:
+ assert e.message_dict['name'][0] == "I am happy to see you 42."
class TestUserSerializer():
def test_name(self) -> None:
diff --git a/stack_example/user/models.py b/stack_example/user/models.py
index 2d03e7a..7d92470 100644
--- a/stack_example/user/models.py
+++ b/stack_example/user/models.py
@@ -8,4 +8,4 @@ from django.contrib.auth.models import (
class User(AbstractBaseUser, PermissionsMixin):
name = models.CharField("Name", max_length=42, null=True,
- error_messages={'max_length':"I am happy to see you {max_length}."})
+ error_messages={'max_length':"I am happy to see you %(limit_value)s."})
diff --git a/stack_example/user/serializers.py b/stack_example/user/serializers.py
index ddd86ce..704f844 100644
--- a/stack_example/user/serializers.py
+++ b/stack_example/user/serializers.py
@@ -2,10 +2,9 @@ from rest_framework import serializers
from user.models import User
class UserSerializer(serializers.ModelSerializer):
-
class Meta:
model = User
fields = ["name"]
extra_kwargs = {
- "name": {"required": True, "allow_blank": False, "allow_null": False},
- }
+ "name": {"required": True, "allow_blank": False, "allow_null": False, "error_messages": User._meta.get_field('name').error_messages},
+ }
--
2.20.1 (Apple Git-117)
解决方案可浏览on github
关于python - Django Rest Framework 如何在 models.CharField 上设置 error_messages,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66714654/