Автогенерация поля при создании экземпляра модели Django
Есть модель ShareLink, в ней есть поле qrcode_image с типом ImageField. Я хочу, чтобы при создании экземпляра данной модели генерировалось изображение QR-кода и сохранялось в данном поле. Как такое реализовать?
Исходник модели ShareLink:
class ShareLink(models.Model):
slug = models.SlugField(blank=False)
qrcode_image = models.ImageField(upload_to='account/share_link/qr_code/')
schedules = models.TextField(blank=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, blank=False)
users = models.ManyToManyField(User, related_name='sharelinks_used', blank=True)
views = models.IntegerField(default=0)
is_deleted = models.BooleanField(default=False)
def __str__(self):
str = 'ShareLink: id: {}, slug: {}'.format(self.id, self.slug)
return str
Данный исходник генерирует QR-код, и получает изображение:
import qrcode
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=6,
border=0,
)
# Добавляет данные в QR и получает изображение
qr.add_data('ta.taranets')
qr.make(fit=True)
img = qr.make_image()
Как действовать дальше: как сохранять данное изображение по правильному пути и добавить в qrcode_image?
Ответы (2 шт):
Вы можете переопределить метод save, генерируя в нём это поле.
Пример:
from django.db import models
from django.core.files.base import ContentFile
class ShareLink(models.Model):
qrcode_image = models.ImageField(upload_to='account/share_link/qr_code/')
def save(self, *args, **kwargs):
img_name = ...
img_content = ...
self.qrcode_image.save(img_name, ContentFile(img_content))
super(ShareLink, self).save(*args, **kwargs)
Можно воспользоваться сигналами pre_save или post_save.
С помощью сигнала post_save можно дополнительно получить информацию о том, был ли создан экземпляр (или существовал ранее) и какие поля в нём были изменены (если он не был только что создан).
Пример:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.files.base import ContentFile
@receiver(post_save, sender=ShareLink)
def generate_qrcode(sender, instance, created, update_fields, **kwargs):
img_name = ...
img_content = ...
instance.qrcode_image.save(img_name, ContentFile(img_content))
instance.save()