Работа с изображениями через 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