Marco Del Toro
Marco Del Toro

Reputation: 112

upload image on json DJANGO REST FRAMEWORK

I'm trying to upload an encoded BASE64 image when I register a new user for my app i use a ImageField inside my userprofile the problem is the API gives me the following error.

{
  "userprofile": {
    "photo": [
      "The submitted data was not a file. Check the encoding type on the form."
    ]
  }
}

This is my information in the request I use a POST Request with header Content-Type: application/json for the request i use POSTMAN from google

{

    "username": "is690002",
    "password": "is690002",
    "first_name": "andres ",
    "last_name": "Barragan",
    "email": "[email protected]",
    "userprofile": {
        "gender": "F",
        "phone_number": "3315854644",
        "photo": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYAB......."
    }
  }

This is my model.py

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile')

    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default='M')

    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',message="Phone must be entered in the format: '+999999999'. Up 15 digits allowed.")
    #The Field on DataBase after check if it's a valid Phone Number.
    # validators should be a list
    phone_number = models.CharField(validators=[phone_regex], max_length=15, blank=True) 
    photo = models.ImageField(upload_to = 'C:\ProjectsDJ\carpoolapp\photos', null = True)

my serializers

class UserProfileSerializer(serializers.ModelSerializer):
    photo =  serializers.ImageField(max_length=None, use_url=False)
    class Meta:
        model = UserProfile
        fields = (
            'gender',
            'phone_number',
            'photo'
            )


class UserRegistrationSerializer(serializers.HyperlinkedModelSerializer):
    userprofile = UserProfileSerializer()
    class Meta:
        model = User
        fields = (
            'username',
            'first_name',
            'last_name',
            'email',
            'password',
            'userprofile'
            )
        extra_kwargs = {'password': {'write_only': True}}

#@Override create for create a user and profile from HTTP Request
    def create(self, validated_data): #
            userprofile_data = validated_data.pop('userprofile')
            user = User.objects.create(**validated_data) # Create the user object instance before store in the DB
            user.set_password(validated_data['password']) #Hash to the Password of the user instance
            user.save() #Save the Hashed Password
            UserProfile.objects.create(user=user, **userprofile_data)
            return user #Return user object

and my View.py

class UserRegister(APIView):

    permission_classes = ()
    def post(self, request):
        serializer = UserRegistrationSerializer(data = request.data) #, files = request.FILES)
        serializer.is_valid(raise_exception=True) # If the JSON Is
        serializer.save() #Save user in DB
        return Response(status=status.HTTP_201_CREATED)

NOTE: everything is fine if i dont use the imageField i can create my user etc, also i tried two tutorials here in StackOverflow

Upvotes: 2

Views: 7084

Answers (2)

Edder Ramírez
Edder Ramírez

Reputation: 1

for registering user RegisterSerializer

class RegistrationSerializer(RegisterSerializer):

    """
    Formulario de registro personalizado
    """
    first_name = serializers.CharField(max_length=50)
    last_name = serializers.CharField(max_length=50)
    phone_number = serializers.CharField(max_length=30)
    street_name = serializers.CharField(max_length=50)
    int_number = serializers.CharField(max_length=5)
    ext_number = serializers.CharField(max_length=5)
    suburb = serializers.CharField(max_length=60)
    city = serializers.CharField(max_length=60)
    cp = serializers.CharField(max_length=50)
    state = serializers.CharField(max_length=60)
    backup_phone = serializers.CharField(max_length=30, allow_blank=True)
    curp = serializers.CharField(max_length=50)

    avatar = serializers.ImageField(allow_empty_file=True, required=False)

def get_cleaned_data(self):
    pass

def save(self, request):

    pass

it worked for me.

in postman enter image description here

Upvotes: 0

Linovia
Linovia

Reputation: 20996

Django REST framework doesn't support out of the box file upload through JSON. The documentation mentions that. Maybe a 3rd party does.

Note that the file upload tests in DRF do use the form content type instead of JSON.

Upvotes: 4

Related Questions