#python #django #file #base64 #storage
#python #django #файл #base64 #Хранение
Вопрос:
models.py:
class Empresa(models.Model):
logo = models.FileField(null=True)
forms.py:
class ConfiEmpresa(ModelForm):
logo = forms.FileField(required=False)
class Meta:
model = Empresa
Следующий код ввода html, который отображается в поле формы:
<input type="file" name="logo" id="id_logo">
views.py:
import base64
def configempresa(request):
if request.method == "POST":
form = ConfiEmpresa(request.POST, request.FILES)
print(form.errors) # I'm not having any form error here
if form.is_valid():
logo = form.cleaned_data.get('logo')
print(logo) # It's printing "None"
logo = base64.encodebytes(logo)
#...rest of the view
Ошибка, которую я получаю:
TypeError at /Config/empresa/
expected bytes-like object, not NoneType
Итак, в заключение я пытаюсь преобразовать файл jpg, который пользователь задает как ‘logo’, в base64, чтобы сохранить его в моей БД и позже декодировать его, чтобы получить изображение там, где оно мне нужно.
Конечно, я делаю что-то не так, я думаю, это на мой взгляд. Как я могу обработать значение поля формы logo
, чтобы преобразовать его в base64?
Я не сохраняю необработанный файл ни в какой папке.
Комментарии:
1. Вы уверены, что ваш файл отправлен? Если вы проверите,
request.FILES
есть ли там что-нибудь? Кроме того, использовали ли вы<form enctype="multipart/form-data" ...>
в качестве типа кодировки формы?2. Кроме того, учитывая, что ваше поле является
required=False
, это означает, что вы разрешаете НЕ отправлять файл, поэтому вам нужно будет обработать случай, когда логотип не загружается.3. Спасибо @Geekfish. Ну, тип enctype был частью проблемы. Это было в «application / x-www-form-urlencoded». Теперь он больше не выводит «None», но ошибка теперь такая: «ожидаемый байтоподобный объект, а не InMemoryUploadedFile»
4. Также мне интересно, правильно ли «logo = form.cleaned_data.get(‘logo’)» и «logo = base64.encodebytes(logo)»?
5. Подсказка содержится в сообщении об ошибке. Вы пытаетесь передать
InMemoryUploadedFile
объект (logo
) вbase64.encodebytes
, который, как следует из названия, ожидает байты.InMemoryUploadedFile
является оболочкой вокруг фактического файла. Вам нужно получить фактическое содержимое файла. Что-то вродеbase64.encodebytes(logo.file.read())
. Но я не уверен в точном способе. Возможно, вам потребуется поискать, как именно это сделать.
Ответ №1:
Не было бы лучше сохранить логотип в ImageField
?
Если вы хотите сохранить изображение base64, вы всегда можете сохранить его в TextField
виде строки, если вы только хотите показать изображение позже.
Комментарии:
1. Это неверный ответ на вопрос, однако предложение использовать
TextField
хорошее.2. Да, текстовое поле в модели. Форма подходит для FileField.
Ответ №2:
Решение:
if form.is_valid():
logo = form.cleaned_data.get('logo')
print(logo)
logo = base64.b64encode(logo.file.read())