Omonbude Emmanuel
Software Engineer
HTML/CSS/JAVASCRIPT
PYTHON
DJANGO/DJANGO REST FRAMEWORK
NODE JS
DOCKER, AWS, KUBERNATES
FIREBASE, PostgreSQL, MySQL,Mongo DB
FLUTTER
DART
ANGULAR
TYPESCRIPT

Base64 images with django rest framework

Omonbude Emmanuel | July 9, 2023, 9:45 a.m.

151

Introduction

Base64 encoding is a technique to convert binary data into an ASCII string format. When dealing with APIs, Base64 is useful for transmitting image data in JSON payloads, making it easier to handle image uploads without requiring multipart form data. Django Rest Framework (DRF) is a powerful toolkit for building Web APIs in Django, and it provides the flexibility needed to handle Base64 images.

This tutorial will cover:

  1. Setting up a Django project and app.
  2. Creating a model to store image data.
  3. Writing a serializer to handle Base64 image input.
  4. Updating views to process the image data.
  5. Testing the image upload functionality.

Steps

Step 1: Setting Up the Django Project

First, create a new Django project and app. Install Django and DRF if you haven't already.

 

pip install django djangorestframework
django-admin startproject myproject
cd myproject
python3 manage.py startapp myapp


 

Add rest_framework and your app to the INSTALLED_APPS in settings.py.

 

# myproject/settings.py

INSTALLED_APPS = [ ... 'rest_framework', 'myapp', ]

Step 2: Creating the Model

Create a model to store the image data. In this example, we'll create a simple model with an ImageField.

 

# myapp/models.py
from django.db import models
class ImageModel(models.Model):
    image = models.ImageField(upload_to='images/')

 

python manage.py makemigrations
python manage.py migrate

Step 3: Writing the Serializer

Create a serializer to handle the Base64 encoded image. We'll use a custom field to handle the Base64 decoding.

 

from django.core.files.uploadedfile import InMemoryUploadedFile
from .models import ImageModel

class ImageByteField(serializers.Field):
    def to_internal_value(self, data):# Assuming data is already bytes
        return data
    def to_representation(self, value):
        # Encode bytes to base64 for representation
        return base64.b64encode(value).decode('utf-8')

 

class ImageSerializer(serializers.ModelSerializer):
    image = ImageByteField(required=False)
    class Meta:
        model = ImageModel
        fields = ('id', 'image')


    def create(self, data):  
        serialized_image = data.get('image')
        #convert base 64 bytes to image file
        image = InMemoryUploadedFile(
            serialized_image, 
            None, 
            'image.jpg',  # Or dynamically determine the name and extension
            'image/jpeg', # Or dynamically determine the content type
            None,# Add the file size
            None)  # Charset is optional, so pass None 
        return ImageModel.objects.create(image=image)

 

Step 4: Updating the Views

# myapp/views.py

from rest_framework.status import (
    HTTP_400_BAD_REQUEST,
    HTTP_201_CREATED, 
)
from rest_framework import generics
from .serializer import ImageSerializer
from rest_framework.response import Response

class ImageCreateAPIView(generics.CreateAPIView):
    serializer_class = ImageSerializer
    def post(self, request, format=None):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            data = serializer.save()
            data = {'image': data.image.url}
            return Response(data, status=HTTP_201_CREATED)
        else:
            data = {"message": serializer.errors}            
            return Response(data, status=HTTP_400_BAD_REQUEST)

Configure the URLs to include the new viewset.

# myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp.views import ImageCreateAPIView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/images/', ImageCreateAPIView.as_view(), name='image-create'),
]

Step 5: Testing the Image Upload

With the setup complete, you can now test the image upload functionality. Use a tool like Postman to send a POST request to the /api/images/ endpoint with a JSON payload containing the Base64 encoded image data.

Example JSON payload:

{ "image": "/9j/4AAQSkZJRgABAQAAAQABAAD..." }

Conclusion

Handling Base64 images in Django Rest Framework is a straightforward process. By creating a custom serializer field, you can seamlessly decode Base64 image data and save it to your models. This approach simplifies image handling in APIs, making it easier to work with JSON payloads without the need for multipart form data. With this guide, you should be able to implement Base64 image uploads in your own Django projects efficiently.

 

 

 

 

© 2024 Omonbude Emmanuel

Omonbude Emmanuel