Django - сохранение списка изображений base64
У меня есть проект django и django restframework с postgres в качестве базы данных. Я посылаю полезную нагрузку из фронтенда в этот проект django, эта нагрузка представляет собой json и имеет одно поле с именем images. images содержит список base64 изображений. Поэтому я хочу сохранить их в базе данных и использую следующий код для этого поля:
images = ArrayField(base_field=models.ImageField(upload_to='hotel_images/'))
но когда я хочу сохранить изображения, я получаю эту ошибку:
images: ["The submitted data was not a file. Check the encoding type on the form."]
Я понимаю, что мне нужно декодировать base64, чтобы сохранить их в imageField, но как мне это сделать? Как мне декодировать base64 эти изображения в списке по одному? Или вы знаете лучший способ для этого?
вот некоторые из моих кодов:
serializer.py
class HotelsSerializer(serializers.ModelSerializer):
class Meta:
fields = ("id", "name", "stars", "address", "description", "number_of_floors",
"number_of_rooms", "room_delivery_time", "room_empty_time",
"images", "features")
model = Hotel
models.py
class Hotel(models.Model):
"""
model for create a hotel
"""
name = models.CharField(max_length=60, unique=True)
stars = models.IntegerField()
address = models.CharField(max_length=150)
description = models.TextField(default="nitro hotel")
number_of_floors = models.IntegerField()
number_of_rooms = models.IntegerField()
room_delivery_time = models.TimeField()
room_empty_time = models.TimeField()
images = ArrayField(base_field=models.ImageField(upload_to='hotel_images/'))
features = models.JSONField()
def __str__(self) -> str:
return self.name
views.py
class AddHotel(generics.CreateAPIView):
queryset = Hotel.objects.all()
serializer_class = HotelsSerializer
Проблема в том, что изображение в кодировке b64 по своей сути не является файлом, возможно, вы можете изменить вашу модель, чтобы она содержала JSON или StringField.
В качестве альтернативы вы можете преобразовать ваш B64 в поток файлов и загрузить его таким образом.
Используя класс ContentFile (https://docs.djangoproject.com/en/4.0/ref/files/file/#the-contentfile-class) Django, вы можете инициализировать файл на лету и попытаться сохранить его.
image_file = ContentFile(base64.b64decode(data), name="smart_name.jpg")
Этот трюк должен сработать, вам может потребоваться предварительная обработка строки base-64 в зависимости от того, как вы ее генерируете.