Pavan Webbeez
Pavan Webbeez

Reputation: 219

unable to change validate field error message in Model serializer

I'm working on ModelSerializer I'm facing these below issues.

1) Unable to validate .validate(self, data) method as I want to return a custom validator message which is not working.

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

below is the screen shot of my output

validation output while creating new object

Hope is have explained my problem well.

Thank you.

Upvotes: 3

Views: 2296

Answers (1)

Micky Loo
Micky Loo

Reputation: 1493

You can define extra_kwargs in the class Meta of your serializer to customize error messages. https://www.django-rest-framework.org/api-guide/serializers/#additional-keyword-arguments

In your case, you would add this to BlogSerializer:

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

The tricky part might be figuring out the key you need to override. Getting the errors raised by the validators in the serializer can be done in the django shell. For example.

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 is the key for the error_messages dictionary. In this case, it is 'blank'.

Upvotes: 5

Related Questions