Используя m2m_changed сигнал
Сначала немного информации о приложении: я хочу иметь возможность загрузить файл PDF, этот файл PDF будет преобразован в изображения (для каждой страницы PDF одно изображение). Эти изображения затем будут показаны на веб-сайте, и PDF-файл можно скачать: пока у меня есть это:
def upload_to(path):
def upload_callback(instance, filename):
return '%s' % os.path.join(settings.MEDIA_ROOT, path, str(instance), filename)
return upload_callback
class Document(models.Model):
name = models.TextField()
pdf_file = models.FileField(upload_to=upload_to('pdfs'))
images = models.ManyToManyField('Image', null=True, blank=True)
class Image(models.Model):
image = models.ImageField(upload_to='pdfimages')
Теперь для создания изображений и объектов изображений я переписал функцию сохранения класса Document: я выгляжу так:
def save(self, *args, **kwargs):
path = os.path.join(settings.MEDIA_ROOT, 'pdfs', self.name)
imagepath = os.path.join(settings.MEDIA_ROOT, 'pdfimages')
if os.path.exists(path):
for file_ in os.listdir(path):
if file_ == self.pdf_file.name:
continue
super(Document, self).save(*args, **kwargs)
save_to = os.path.join(path, os.path.splitext(self.pdf_file.name)[0] +
'_page.png')
pdffile = os.path.join(path, self.pdf_file.name)
args = ['convert', '-density', '100', '-depth',
'8', '-quality', '85', pdffile, save_to ]
subprocess.check_call(args, stdout=sys.stdout, stderr=sys.stderr)
for file_ in os.listdir(path):
if file_.endswith('png'):
try:
shutil.move((os.path.join(settings.MEDIA_ROOT,
'pdfs', self.name, file_)),
imagepath)
except Exception:
pass
for file_ in os.listdir(imagepath):
i, created = Image.objects.get_or_create(image="pdfimages/%s" % file_)
Во-первых, этот код не очень хорош, а во-вторых, самое важное действие все еще отсутствует. Добавление изображения в документ означает обновление отношения m2m. Теперь у меня есть два вопроса:
- Могу ли я написать код выше? (в основном не нравится
super(Document, self).save(*args, **kwargs) в середине кода.
- Для обновления m2m я посмотрел на сигнал m2m_changed, но, честно говоря, не понимаю, как его использовать.
РЕДАКТИРОВАТЬ:
На самом деле это довольно легко, когда вы понимаете параметр, спасибо
1 ответ
Проверьте этот пост на использование сигнала m2m.
Вы можете переместить всю свою логику обработки сохранения записи в сигнал