Question

Why raising serializers.ValidationError() is causing UnicodeDecodeError?

I am creating a django rest API(with a ImageField) and it is working fine. But I want to add some validations to some CharFields fields. I noticed some unicodeDecoderError while added a validator or simply raising a validation error. Spent quite a lot of time trying to solve it. Any help will be appreciated.

Here is my serializers.py file

from rest_framework import serializers
from .models import *

def validate_phone(phone_number: str):
  print(phone_number)
  if not (phone_number.startswith(("6", "7", "8", "9"))):
    raise serializers.ValidationError(
        {"phone": "phone number must startwith digits from 6-9 !!!"})

  if not phone_number.isnumeric():
    raise serializers.ValidationError(
         {"phone": "phone number should contain digits only !!!"})

  if len(phone_number) != 10:
     raise serializers.ValidationError(
         {"phone": "phone number must contain only 10 digits !!!"})


class StudentSerializer(serializers.ModelSerializer):
  start_date = serializers.DateField(format='%d %B %Y')
  phone = serializers.CharField(max_length=10, validators=[validate_phone])
  class Meta:
    model = Student
    fields = '__all__'

Raising a validation error is resulting a UnicodeDecoderError. Working fine otherwise.

This is my models.py file

from django.db import models

class Student(models.Model):
    ...
    phone = models.CharField(max_length=10)
    ...
    start_date = models.DateField()
    profile_picture = models.ImageField(upload_to='profile/', blank=True)
    ...

views.py

class CreateStudent(APIView):
    def get(self, request):
        students = Student.objects.all()
        serializer =  StudentSerializer(students, many=True)
        return Response({"data": serializer.data}, status=status.HTTP_200_OK)

    def post(self, request):
        data = request.data
        print(data)
        serializer = StudentSerializer(data = data)

        if serializer.is_valid():
            print("\nThis record is valid.")
            new_student = serializer.save()
            print(new_student.id)
            return Response({"message": "Data saved Successfully.", "data": serializer.data, "errors": serializer.errors})
        return Response({"message": "Invalid Data", "data": serializer.data, "errors": serializer.errors})

I am sending the data using javascript fetch API with FormData() which handles the file formatting and encoding.

Here is the javascript file:

const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
  e.preventDefault();

  const formdata = new FormData(form);
  const json_data = Object.fromEntries(formdata);
  console.log(json_data);

  const requestOptions = {
    method: 'POST',
    body: formdata,
  };

  fetch("http://127.0.0.1:8000/api/join/", requestOptions)
    .then((response) => response.json())
    .then((result) => console.log(result))
    .catch((error) => console.error(error))

Feeling helpless. Without raising a ValidationError it is working fine, I just want to add some validations without any UnicodeDecodeError. I tried to test with postman and the result is same. I do not know how to proceed.

Where am I missing

here is the full traceback:

[05/Jul/2024 08:31:03] "POST /api/join/ HTTP/1.1" 200 316
Internal Server Error: /api/join/
Traceback (most recent call last):
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\django\core\handlers\base.py", line 220, in _get_response
    response = response.render()
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\django\template\response.py", line 114, in render
    self.content = self.rendered_content
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\rest_framework\response.py", line 74, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\rest_framework\renderers.py", line 100, in render
    ret = json.dumps(
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\rest_framework\utils\json.py", line 25, in dumps
    return json.dumps(*args, **kwargs)
  File "C:\Users\lokes\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "C:\Users\lokes\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\lokes\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\lokes\Desktop\Dambaruu\Tasks\Week-7\.api\lib\site-packages\rest_framework\utils\encoders.py", line 52, in default
    return obj.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
 4  56  4
1 Jan 1970

Solution

 0

I think that your problem is here "profile_picture" it's a ImageField, try this in StudentSerializer return profile_picture.url instead profile_picture because profile_picture.url return a string and not a ImageField instance

2024-07-05
Victor Duarte