python - Django Rest Framework 如何在 models.CharField 上设置 error_messages

标签 python django django-rest-framework

嗨!

总结问题

我有一个 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/

相关文章:

python - 降低列表操作的复杂性

python - 设计健全性检查

python - 类型错误 : __init__() got an unexpected keyword argument 'many'

c++ - 将数据从 Django 传递到 C++ 应用程序并返回

python - Django Rest Framework 分页提供小于页面大小

python - 序列化器在 Django shell 中工作但在 View 中失败

python - django.db.utils.ProgrammingError : (1146, "Table ' med_portal.Custparent'不存在”)

python - Heroku 不安装 requirements.txt 中列出的任何内容

python - Windows上的Django安装问题

python - 无法从 python 发送带有附件的电子邮件?