无法更改模型序列化器中的验证字段错误消息

时间:2019-04-07 13:19:22

标签: python django django-rest-framework django-serializer django-validation

我正在研究ModelSerializer,但遇到了以下这些问题。

1)无法验证.validate(self, data)方法,因为我想返回无效的自定义验证器消息。

model.py

class BlogModel(models.Model):

    BLOG_STATUS = (
        ('PUBLISH', 'Publish'),
        ('DRAFT', 'Draft'),
    )

    blog_id = models.AutoField(primary_key=True)
    user = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name='blogs')
    title = models.CharField(max_length=255)
    content = models.TextField(blank=True, null=True)
    status = models.CharField(max_length=7, choices=BLOG_STATUS)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta():
        db_table = 'blogs'
        verbose_name = 'Blog'
        verbose_name_plural = 'Blogs'

    def __str__(self):
        return self.title

serializers.py


import datetime
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer,Serializer
from blogs.models import BlogModel, BlogFilesModel

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
        # exclude = ['password']


class BlogFilesSerializer(ModelSerializer):
    count_files = serializers.IntegerField(required=False)

    class Meta:
        model = BlogFilesModel
        fields = ('blog_files_id', 'blog', 'path',
                  'created_at', 'updated_at', 'count_files')

    def get_path(self, obj):
        formatted_date = obj.created_at.strftime("%d-%m-%Y")
        return formatted_date

class BlogSerializer(ModelSerializer):
    blog_files = serializers.SerializerMethodField()

    def get_blog_files(self, obj):
        info = BlogFilesSerializer(BlogFilesModel.objects.filter(
            blog=obj).order_by('-pk'), many=True)

        if info.data:
            for i in info.data:
                user_detail = User.objects.get(pk=obj.user.id)
                i.__setitem__('user_detail', UserSerializer(user_detail).data)
                if i.get('user_detail'):
                    try:
                        del i['user_detail']['password']
                    except expression as identifier:
                        pass

        return info.data

    blog_created_at=serializers.SerializerMethodField()

    def get_blog_created_at(self, obj):
        formatted_date=obj.created_at.strftime("%d-%m-%Y")
        return formatted_date

    def validate(self, data):
        if data.get('title') == "":
            #this below error message not showing
            raise serializers.ValidationError("Title field must not be left blank.") 
        return data

    def validate_title(self, value):
        if value != "Hello":
            raise serializers.ValidationError("Title field must be 'Hello' ")
        return value

    def validate_content(self, value):
        if len(value) < 2:
            raise serializers.ValidationError("Content must have at least 2 letters")
        return value

    class Meta:
        model=BlogModel
        fields=('blog_id', 'user', 'title', 'content',
                  'status', 'blog_files', 'blog_created_at')


views.py


class BlogViewSet(viewsets.ModelViewSet):
    queryset = BlogModel.objects.all()
    lookup_field = 'blog_id'
    serializer_class = BlogSerializer

下面是我的输出的屏幕截图

validation output while creating new object

希望很好地解释了我的问题。

谢谢。

1 个答案:

答案 0 :(得分:2)

您可以在序列化程序的Meta类中定义extra_kwargs,以自定义错误消息。 https://www.django-rest-framework.org/api-guide/serializers/#additional-keyword-arguments

在您的情况下,您可以将其添加到BlogSerializer:

    extra_kwargs = {
        'title': {
            'error_messages': {
                'blank': 'my custom error message for title'
            }
        }
    }

棘手的部分可能是弄清楚您需要覆盖的密钥。可以在django shell中完成由验证器在序列化器中引发的错误。例如。

serializer = BlogSerializer(data={'title':''})
serializer.is_valid()
serializer._errors

{'status': [ErrorDetail(string=u'This field is required.', code=u'required')]
 'title': [ErrorDetail(string=u'This field may not be blank.', code=u'blank')
 'user': [ErrorDetail(string=u'This field is required.', code=u'required')]}

ErrorDetail.code是error_messages字典的键。在这种情况下,它是“空白”。