I have a Django Rest Framework backend, on which I want to do a simple thing: change default validation message :
'max_length': _('Ensure this field has no more than {max_length} characters.'),
To a custom one like
'max_length': 'I am happy to see you {max_length}.'
methods that failed are on the bottom of this post
You can pull a minimal example from git repo , and run tests by calling 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."
error messages seem to be ignored.
error_messages
as a CharField argument (as shown in example) validators=[MaxLengthValidator(42, message="I am happy to see you {max_length}.")]
CharField
class. Maybe I didnt understand their solution, because inheriting from fields.CharField
didnt allow me to set stuff into init method (I use model.CharField
, they use field.Charfield
. It didnt work either way.def validate_name(self, value):
inside UserSerializer
. It is also ignored. Feel free to git am
this. Explanation in the commit message.
Also fixed the display of the value and added a test to make sure the override works at the model level.
From b5e0b90d8aea9348ef0de7624ad1460c06a2c44e Mon Sep 17 00:00:00 2001
From: Melvyn <melvyn@stackexchange.site>
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)
Solution can be browsed on github
What I saw from your attempts was that you inherited CharField correctly but applied it to the model field when the right thing to do would be to use it in the serializer. That work for me:
from rest_framework import serializers
from rest_framework.fields import CharField
from django.utils.translation import gettext_lazy as _
from user.models import User
class CustomCharField(CharField):
default_error_messages = {
'max_length': _('I am happy to see you {max_length}.'),
}
class UserSerializer(serializers.ModelSerializer):
name = CustomCharField(required=True, allow_blank=False, allow_null=False, max_length=42)
class Meta:
model = User
fields = ["name"]
# extra_kwargs = {
# "name": {"required": True, "allow_blank": False, "allow_null": False},
# }
This solution can be browsed on guthub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.