Как отправить Django FileField по электронной почте в виде вложения? - PullRequest
6 голосов
/ 28 июня 2011

Мне нужно отправить models.FileField в качестве вложения электронной почты, используя Django.Я видел фрагменты, которые показывают, как сделать это с необработанными данными request.FILES (которые все еще содержат тип контента), но не смог найти ничего, что показывает, как это сделать, когда вы уже сохранили файлв models.FileField.Тип контента кажется недоступным из models.FileField.

Может кто-нибудь привести пример того, как это будет работать?Я начинаю думать, что мне, возможно, придется сохранять тип содержимого в модели при сохранении файла.

Спасибо!

Ответы [ 4 ]

14 голосов
/ 22 ноября 2011

Присоединение файла models.FileField к сообщению электронной почты - это удобно и просто в Django:

from django.core.mail import EmailMultiAlternatives
kwargs = dict(
    to=to,
    from_email=from_addr,
    subject=subject,
    body=text_content,
    alternatives=((html_content, 'text/html'),)
)
message = EmailMultiAlternatives(**kwargs)
message.attach_file(model_instance.filefield.path)
message.send()
4 голосов
/ 13 июня 2012

Другой подход:

from django.core.mail.message import EmailMessage

msg = EmailMessage(subject=my_subject, body=my_email_body, 
      from_email=settings.DEFAULT_FROM_EMAIL, to=[to_addressed])
msg.attach_file(self.my_filefield.file) # self.my_filefield.path for Django 1.7+
msg.send(fail_silently=not(settings.DEBUG))
1 голос
/ 30 января 2019

Я использую Джанго-хранилища и так .path повышает

NotImplementedError: This backend doesn't support absolute paths.

Чтобы избежать этого, я просто открываю файл, читаю его, угадываю mimetype и закрываю его позже, но нужно использовать .attach вместо .attach_file magic.

from mimetypes import guess_type
from os.path import basename


f = model.filefield
f.open()
# msg.attach(filename, content, mimetype)
msg.attach(basename(f.name), f.read(), guess_type(f.name)[0])
f.close()
0 голосов
/ 28 июня 2011

Я бы просто не предоставил тип контента и не позволил бы клиенту электронной почты получателя решить это. Если это не будет чем-то необычным, это не должно быть проблемой.

RFC2616 состояния:

Если и только если тип носителя не заданный полем Content-Type, получатель МОЖЕТ попытаться угадать тип носителя через проверку его содержание и / или расширение имени URI, используемый для идентификации ресурс.

но ... Если вы хотите указать это, то сохранение типа контента при загрузке - очень хорошая идея. Следует отметить, что собственные документы django говорят проверить данные пользователей

Если вы работаете в * unix ОС, вы можете попытаться угадать / проверить это:

import subprocess
subprocess.check_output(['file', '-b', '--mime', filename]) 

(из Как найти mime-тип файла в python? )

...