情景非常简单:
我有一个模型,其中包含一些必填字段。我们说其中一个是TextField
,不能是blank
。
我还有一个代表该模型的ModelSerializer
(Django Rest Framework)。
当使用空字符串通过序列化程序设置该字段时,返回的错误来自模型本身(This field can't be blank
)。
我想仅在序列化程序级别覆盖错误消息,而无需显式重新指定序列化程序中的每个字段(我认为这违反了DRY原则),必须编写validate_
每个字段的方法,并引发我自己的ValidationError
或必须更改Model
级别的错误消息(因为有时错误消息的上下文对我的用例很重要,应该给出错误消息相应地)。
换句话说,有没有办法在序列化程序级别覆盖错误消息,就像ModelForm
一样简单:
class MyModelForm(ModelForm):
class Meta:
model = MyModel
error_messages = {"field1": {"required": _("For some reason this is a custom error message overriding the model's default")}}
答案 0 :(得分:24)
编辑:我看到这个问题仍然会收到一些观点,因此请务必注意另一种方法,比我在此处发布的原始答案要清晰得多。
您可以使用序列化程序的Meta类的extra_kwargs属性,如下所示:
class UserSerializer(ModelSerializer):
class Meta:
model = User
extra_kwargs = {"username": {"error_messages": {"required": "Give yourself a username"}}}
原始回答:
使用@mariodev的回答我在我的项目中创建了一个新类:
from rest_framework.serializers import ModelSerializer, ModelSerializerOptions
class CustomErrorMessagesModelSerializerOptions(ModelSerializerOptions):
"""
Meta class options for CustomErrorMessagesModelSerializerOptions
"""
def __init__(self, meta):
super(CustomErrorMessagesModelSerializerOptions, self).__init__(meta)
self.error_messages = getattr(meta, 'error_messages', {})
class CustomErrorMessagesModelSerializer(ModelSerializer):
_options_class = CustomErrorMessagesModelSerializerOptions
def __init__(self, *args, **kwargs):
super(CustomErrorMessagesModelSerializer, self).__init__(*args, **kwargs)
# Run through all error messages provided in the Meta class and update
for field_name, err_dict in self.opts.error_messages.iteritems():
self.fields[field_name].error_messages.update(err_dict)
第一个可以像Meta
一样向序列化程序添加新的ModelForm
类属性。
第二个继承自ModelSerializer
并使用@ mariodev技术更新错误消息。
只剩下一切,只是继承它,并做类似的事情:
class UserSerializer(CustomErrorMessagesModelSerializer):
class Meta:
model = User
error_messages = {"username": {"required": "Give yourself a username"}}
答案 1 :(得分:18)
在序列化程序中:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs)
self.fields['username'].error_messages['required'] = u'My custom required msg'
请注意,某些错误消息包含%s
占位符,例如:
'invalid': _("'%s' value must be either True or False."),
代表BooleanField
。
因此,您需要在DRF fields.py
中的每个字段类型中查看default_error_messages
部分,才能正确使用它。
答案 2 :(得分:10)
unique
似乎被error_messages
忽略了,所以我不得不采取不同的方法。
email = serializers.EmailField(validators=[
UniqueValidator(
queryset=models.Client.objects.all(),
message="My custom error",
)]
)
它比@ gabriel-amram更简单(但更不灵活,更不可重复使用),但远不如@ mariodev那么简单。
答案 3 :(得分:4)
UniqueValidator的另一种方法(与ModelSerializer一起使用):
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs)
# Find UniqueValidator and set custom message
for validator in self.fields['email'].validators:
if isinstance(validator, validators.UniqueValidator):
validator.message = _('This email already exist on this site')
答案 4 :(得分:2)
我试图创建一个简单的Serializer
而不是ModelSerializer
。可能是因为这样,Gabriel Amram接受extra_kwargs
接受的答案对我没有用。 @mariodev的另一个最佳答案确实起作用了,但我正在寻找一种更优雅的解决方案,并找到了一个。事实证明Field
类接受error_messages
作为参数,这是一个覆盖默认错误消息的字典。这是reference to the docs。与接受的答案中所述的格式相同。这是一个示例:
from rest_framework import serializers
class MySerializer(serializers.Serializer):
client_id = serializers.IntegerField(required=True, error_messages={'required': 'Custom error message'})
答案 5 :(得分:1)
我刚刚花了一个小时将头发扯掉,所以想在其他人觉得有用的情况下在这里发布更新。
我正在使用djangorestframework版本3.10.3,无论出于何种原因,看来drf不再使用error_messages字典中的“ required”键来允许为缺少的值定制错误消息。相反,它使用“空白”。
class SampleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = SampleModel
fields = (
'description',
)
extra_kwargs = {
'description': {'error_messages': {'blank': "Please provide a description"}},
}
答案 6 :(得分:0)
自从我玩了一段时间以来只是一个注释,如果你使用像URLField那样只添加一个URLValidator,它似乎没有使用error_messages
,所以我做了类似于@的事情。雨果的回答:
class Meta:
extra_kwargs = {"url_field": {"validators": [validators.URLValidator(message="My error message")]}}
答案 7 :(得分:0)
如果我们希望覆盖默认的模型验证器,DRF3.0希望我们明确定义字段的验证器。这可以通过传递extra_kwargs并为任何字段显式定义验证器来完成 你似乎有必要。您甚至可以指定自己的自定义验证器,可以再次为不同的字段或其他序列化器重复使用
http://www.django-rest-framework.org/api-guide/serializers/#validation
http://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework
top: scrollTop < originalY
? 0
: scrollTop - originalY + topMargin
答案 8 :(得分:-1)
这是继承模型错误信息的代码。
还有一个模块,所以如果你想下载它。
如果有问题,请在评论中留言。
https://pypi.org/project/django-rest-inherits-error-messages/#files
from rest_framework import serializers
from rest_framework.relations import HyperlinkedRelatedField
from rest_framework.utils.field_mapping import get_nested_relation_kwargs
class InheritsModelSerializer(serializers.ModelSerializer):
def build_field(self, field_name, info, model_class, nested_depth):
'''
inherits the error_messages of the model
'''
result: tuple = super().build_field(field_name, info, model_class, nested_depth)
field = model_class._meta.get_field(field_name)
error_messages = field.error_messages
if error_messages:
result[1]['error_messages'] = field.error_messages
return result