Home > Net >  How to send images to DRF with json request?
How to send images to DRF with json request?

Time:02-27

I am working on an e-commerce project, and I want to add products from the front end. The files in my product app in Django is as follows

models.py:

from django.db import models
from django.forms import CharField
from PIL import Image
from io import BytesIO
from django.core.files import File

# Create your models here.

class Category(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField()

    class Meta:
        ordering = ('name',)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return f'/{self.slug}/'

class Product(models.Model):
    category = models.ForeignKey(Category, related_name='product', on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    description = models.TextField(blank=True, null=True)
    price = models.DecimalField(decimal_places=6, max_digits=6)
    image = models.ImageField(upload_to='uploads/', blank=True, null=True)
    thumbnail = models.ImageField(upload_to='uploads/', blank=True, null=True)
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-date_added',)

    def __str__(self):
        return self.name

    
    def create_thumbnail(self, image, size = (300,200)):
        img = Image.open(image)
        img.convert('RGB')
        img.thumbnail(size)

        thumb_io = BytesIO()
        img.save(thumb_io, 'JPEG')

        thumbnail = File(thumb_io, name=image.name)

        return thumbnail

    def get_image(self):
        if self.image:
            return f'http://localhost:8000'   self.image.url
        else:
            return ''

    def get_thumbnail(self):
        if self.thumbnail:
            return f'http://localhost:8000'   self.thumbnail.url
        else:
            if self.image:
                self.thumbnail = self.create_thumbnail(self.image)
                self.save()
                return f'http://localhost:8000'   self.thumbnail.url
            else:
                return '' 

    def get_absolute_url(self):
        return f'/{self.slug}/'

views.py:

from sys import excepthook
from unicodedata import category
from django.http import Http404
from django.shortcuts import render
from .serializers import ProductSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Product
from rest_framework import status 
# Create your views here.


class LastestProduct(APIView):

    def get(self, request, format=None):
        products = Product.objects.all()[0:4]
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)



class Productclass LastestProduct(APIView):

    def get(self, request, format=None):
        products = Product.objects.all()[0:4]
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)



class ProductDetail(APIView):

    def get_object(self, category_slug, product_slug):
        try:
            return Product.objects.filter(category__slug = category_slug).get(slug=product_slug)
        except Product.DoesNotExits:
            raise Http404 

    def get(self, request, category_slug, product_slug, format=None):
        product = self.get_object(category_slug, product_slug)
        serializer = ProductSerializer(product)
        return Response(serializer.data, status=status.HTTP_200_OK)(APIView):

    def get_object(self, category_slug, product_slug):
        try:
            return Product.objects.filter(category__slug = category_slug).get(slug=product_slug)
        except Product.DoesNotExits:
            raise Http404 

    def get(self, request, category_slug, product_slug, format=None):
        product = self.get_object(category_slug, product_slug)
        serializer = ProductSerializer(product)
        return Response(serializer.data, status=status.HTTP_200_OK)

serializers.py:

from dataclasses import fields
from pyexpat import model
from rest_framework import serializers

from .models import Product


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = [
            'id',
            'name',
            'category',
            'get_absolute_url',
            'description',
            'price',
            'get_image',
            'get_thumbnail',
        ]

It works fine when it comes to fetching data (products I created in the Django admin) but how to send a JSON request that also contains the images as well as the text data like name, description etc. Currently, I can create a product by sending a POST request but the cannot send an image to the endpoint

CodePudding user response:

Actually, you don't. If you want to send a file, you'd better send it as a multipart/formdata not json. In DRF, this requires you change the default parser of your view. See: https://www.django-rest-framework.org/api-guide/parsers/#multipartparser

But, if you really need to use a json format, I guess you could transform your file into a str representation (in the front - check base64 encoding) then send it in a json and finally transform the str representation into a file in the back. However, I would not advise you to do this as it makes the process more cumbersome

  • Related