Сохранение декодированного временного изображения в поле Django Imagefield
Я пытаюсь сохранить изображения, которые были переданы мне как кодированный текст Base64 в поле изображений Django.
но, похоже, он не сохраняет правильно. База данных сообщает, что все мои изображения хранятся как"", когда она должна сообщить о них как имя файла, например:
"template_images/template_folders/myImage.png"
код, который пытается спасти мои изображения выглядит следующим образом:
elif model_field.get_internal_type() == "ImageField" or model_field.get_internal_type() == "FileField": # Convert files from base64 back to a file.
if field_elt.text is not None:
setattr(instance, model_field.name, File(b64decode(field_elt.text)))
3 ответов
после прочтения ответ, я получил эту работу:
from base64 import b64decode
from django.core.files.base import ContentFile
image_data = b64decode(b64_text)
my_model_instance.cool_image_field = ContentFile(image_data, 'whatup.png')
my_model_instance.save()
поэтому, я предлагаю вам изменить ваш код:
from django.core.files.base import ContentFile
# Your other code...
elif model_field.get_internal_type() == "ImageField" or model_field.get_internal_type() == "FileField": # Convert files from base64 back to a file.
if field_elt.text is not None:
image_data = b64decode(field_elt.text)
setattr(instance, model_field.name, ContentFile(image_data, 'myImage.png'))
тогда, если ImageField
определен с
Я думаю, это самый чистый и короткий путь для этого.
вот как вы можете обрабатывать файл изображения в кодировке Base64 в запросе post в конце API на основе Django (drf также), который сохраняет его как ImageField.
Допустим у вас есть модель следующим образом:
Class MyImageModel(models.Model):
image = models.ImageField(upload_to = 'geo_entity_pic')
data=model.CharField()
таким образом, соответствующий сериализатор будет следующим:
from drf_extra_fields.fields import Base64ImageField
Class MyImageModelSerializer(serializers.ModelSerializers):
image=Base64ImageField()
class meta:
model=MyImageModel
fields= ('data','image')
def create(self, validated_data):
image=validated_data.pop('image')
data=validated_data.pop('data')
return MyImageModel.objects.create(data=data,image=image)
соответствующий вид может быть следующим:
elif request.method == 'POST':
serializer = MyImageModelSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
уведомление в Сериализаторе, который я использовал Реализация Base64ImageField предусмотрена в модуле Джанго-дополнительное поле
для установки этого модуля выполните команду
pip install pip install django-extra-fields
импорт то же самое и сделано!
отправить (с помощью метода post) изображение в виде закодированной строки Base64 в объекте JSON вместе с любыми другими данными, которые у вас есть.
еще один хороший подход, основанный на этом so ответ:https://stackoverflow.com/a/28036805/6143656 попробовал и протестировал в django 1.10
Я сделал функцию для декодированного файла base64.
def decode_base64_file(data):
def get_file_extension(file_name, decoded_file):
import imghdr
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
TypeError('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension, )
return ContentFile(decoded_file, name=complete_file_name)
затем вы можете вызвать функцию
import decode_base64_file
p = Post(content='My Picture', image=decode_based64_file(your_base64_file))
p.save()