Работа с изображениями через REST API

Я пытаюсь создать REST API с помощью django-rest-framework, который будет обрабатывать несколько вещей, одна из которых - отправка и получение изображений с фронтенда. Я нашел статью this, которая пытается объяснить идею, но она использует подход на основе классов в своем views.py, а в идеале я хотел бы придерживаться подхода на основе функций, поскольку я уже проделал некоторую работу таким образом (не включая JWT авторизацию) и я бы предпочел, чтобы он остался. Я понятия не имею, как сделать мой бэкенд способным принимать и отправлять изображения, не могли бы вы попытаться предоставить мне фрагменты кода (или, еще лучше, статьи) о том, как это сделать? Заранее спасибо!

В идеале я хочу иметь конечную точку, которая будет обрабатывать создание нового объекта с изображением (точнее, растения), и конечную точку, которая будет обрабатывать обновление (изменение) изображения объекта

Мой models.py:

class Plant(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    name = models.CharField(max_length=150)
    date_added = models.DateField(auto_now_add=True)
    description = models.TextField()
    img = models.ImageField(blank=True, null=True, upload_to=upload_path)
    plant_species = models.CharField(max_length=150)
    last_watered = models.IntegerField(default=0)
    how_often = models.IntegerField(default=0)
    tracked=models.BooleanField(default=True)

Мой views.py:

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['username'] = user.username
        return token

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer


@api_view(['GET'])
def getRoutes(request):
    routes = [
        '/api/token',
        '/api/token/refresh',
        '/api/plants_data',
        '/api/update_plant/<str:pk>'
    ]
    return Response(routes)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def getPlants(request):
    user = request.user
    plants = user.plant_set.all()
    serializer = PlantSerializer(plants, many=True)
    return Response(serializer.data)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def updatePlantTracking(request, pk):
    plant = Plant.objects.get(id=pk)
    serializer = PlantSerializer(instance=plant, data=request.data, partial=True)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=400)

отправляйте изображения или любые медиафайлы в строке json из фронтенда и сделайте поле сериализатора для обработки строки json.

import base64
import uuid
from rest_framework.fields import Field
from rest_framework import serializers

class Base64ContentField(Field):
    """
    For image, send base64 string as json
    """

    def to_internal_value(self, data):
        try:
            format, datastr = data.split(';base64,')
            ext = format.split('/')[-1]
            file = ContentFile(base64.b64decode(datastr), name=str(uuid.uuid4())+'.'+ext)
        except:
            raise serializers.ValidationError('Error in decoding base64 data')
        return file

    def to_representation(self, value):
        if not value:
            return None
        return value.url

Ваш PlantSerializer выглядит как

class PlantSerializer(serializers.ModelSerializer):
    img = Base64ContentField(required=False)
    class Meta:
        model = Plant
        fields = '__all__'

Данные вашего поста с полем img будут выглядеть следующим образом

Вы можете конвертировать изображения в base64 по этой ссылке; Во фронтенде, например reactJS, есть пакеты для преобразования изображения в строку base64

Вернуться на верх