Необходимо переопределить метод сохранения для сохранения в формате base64 из поля Image Django
models.py
def upload_org_logo(instance, filename):
ts = calendar.timegm(time.gmtime())
filepath = f"org_logo/{ts}"
if instance:
filepath = f"org_logo/{instance.org_id}/{instance.org_name}"
base, extension = os.path.splitext(filename.lower())
return filepath
class Organisation(models.Model):
"""
Organisation model
"""
org_id = models.CharField(max_length=50,default=uuid.uuid4, editable=False, unique=True, primary_key=True)
org_name = models.CharField(unique=True,max_length=100)
org_code = models.CharField(unique=True,max_length=20)
org_mail_id = models.EmailField(max_length=100)
org_phone_number = models.CharField(max_length=20)
org_address = models.JSONField(max_length=500, null=True)
product = models.ManyToManyField(Product, related_name='products')
org_logo = models.ImageField(upload_to=upload_org_logo, default='blank.jpg', blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
org_logo_b64 = models.BinaryField(blank=True, null=True)
def save(self, *args, **kwargs):
if self.org_logo:
logo = open(self.org_logo.url, "rb")
print(logo)
self.org_logo_b64 = base64.b64encode(logo.read())
super(Image, self).save(*args, **kwargs)
Когда я пытаюсь отправить сообщение, оно выдает ошибку
FileNotFoundError at /admin/onboarding/organisation/7577ef5f-356c-4cbd-8ef6-e906382447ff/change/
[Errno 2] No such file or directory: '/media/white-logo.png'
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/onboarding/organisation/7577ef5f-356c-4cbd-8ef6-e906382447ff/change/
Django Version: 3.2.12
Exception Type: FileNotFoundError
Exception Value:
[Errno 2] No such file or directory: '/media/white-logo.png'
Exception Location: F:\PM-Onboarding-Service\Onboarding-Service\microservices\onboarding\models.py, line 244, in save
Я попробовал метод, основанный на этом ответе django admin: save image like base64.
Мои настройки для Media следующие:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Может ли кто-нибудь помочь мне сохранить изображение в формате base64 в базе данных, переопределив метод сохранения для поля imagefield?
Обе обновленные и оригинальные версии метода save возвращаются без сохранения в случае отсутствия self.org_logo:
def save(self, *args, **kwargs):
if self.org_logo:
logo = self.org_logo.open()
print(logo)
self.org_logo_b64 = base64.b64encode(logo.read())
super(Organisation, self).save(*args, **kwargs)
Попробуйте добавить return super(Organisation, self).save(*args, **kwargs) в последнюю строку (которая на самом деле является else case) или лучше просто уменьшить отступ текущей последней строки, чтобы она выполнялась и в if и в else случаях:
def save(self, *args, **kwargs):
if self.org_logo:
logo = self.org_logo.open()
print(logo)
self.org_logo_b64 = base64.b64encode(logo.read())
return super(Organisation, self).save(*args, **kwargs)