Задать вопрос
@Egegey

Django. Как правильно сохранить сгенерированный файл в FileField?

Привет!

Я крайне неопытен в Django и мне нужна помощь.
Я попытался переопределить метод save(), чтобы вместе с ним происходила генерация QR кода и последующее сохранение.
Однако при cохранении записи в папке media у меня появляются два файла.
5eb3e75b5416c152823951.png
Один файл ("10.png") состоит из поля slug модели и расширения.
Файл создаётся после выполнения этой строки:
self.qr.save(self.slug+'.png', BytesIO(qr), save=False)

Имя другого файла генерирует сам Django (уже после создания первого) и его же сохраняет в поле qr модели.

Как сделать так, чтобы создавался только один файл ( только "10.png") и в поле сохранялся именно он?

Model.py
class Url(models.Model):
    slug = models.CharField(max_length=50, unique=True)
    qr = models.FileField(upload_to='', blank=True, null=True)

    def save(self, *args, **kwargs):
        qr = self.qr_generate(self.slug)
        self.qr.save(self.slug+'.png', BytesIO(qr), save=False)
        super(Url, self).save(*args, **kwargs)

    def __str__(self):
        return self.slug

    @staticmethod
    def qr_generate(slug):
        qr = qrcode.QRCode(
            version=None,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data("somedata" + str(slug))
        qr.make(fit=True)

        img = qr.make_image(fill_color="black", back_color="white")
        qrByte = BytesIO()
        img.save(qrByte)
        return qrByte.getvalue()
  • Вопрос задан
  • 1196 просмотров
Подписаться 2 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 3
Viji
@Viji
DevOps Engineer
А если убрать super(Url, self).save(*args, **kwargs) ?
Ответ написан
JRazor
@JRazor
Senior StarkOverFlow Programmer
Можно QR вынести в отдельную модель и работать внутри нее с qr кодом. А в URL уже подвязывать объект через OneToOne
Ответ написан
Комментировать
@sanchemba
У меня была такая же проблема. Дело в том, что при самостоятельной привязке файла к полю, видимо, нужно отключить генератор имен файлов в поле FileField и/или включать перезапись файлов. Как это сделать, и можно ли вообще, я пока не разобрался. Очевидно, при сохранении экземпляра модели и, соответственно, поля (в Вашем случае qr), проверяется наличие файла по пути указанному в path (а Вы, если я правильно понимаю, это делаете вызывая self.qr.save()). Если указанный путь "занят", файл не перезаписывается, а генерируется новое имя файла.
Примерно так это работает. Если кто-то подскажет как изменить поведение или переопределить метод save поля FileField, буду очень рад.
Я же сделал довольно топорно:
У меня есть отдельный метод, отвечающий за составление имён файлов, который передаётся в поле upload_to и он то и будет определять конечное имя файла.
В переопределённом методе save() модели я запоминаю путь к файлу, который привязываю к полю FileField. После вызова super(Url, self).save(*args, **kwargs), я просто удаляю временный файл (именно тот, что сам привязывал, а путь к тому, что реально остался определился в методе, передаваемом в upload_to при сохранении модели).
Я делаю сервис для себя, поэтому мне пока норм. Но при большом потоке файлов это может быть довольно накладно. Так что продолжаю искать лучшие пути...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы