How to send Django FileField as an application?

I need to send models.FileField as an email attachment using Django. I saw fragments that show how to do this with raw request.FILES data (which still contain a Content-Type), but could not find anything that shows how to do this once you have already saved the file in models.FileField . The content type seems inaccessible from models.FileField .

Can someone give me an example of how this will work? I'm starting to think that I may need to save the Content-Type in the model when saving the file.

Thanks!

+6
source share
4 answers

I would simply not provide the content type and allow it to the recipient's email client. If this is not unusual, this should not be a problem.

RFC2616 :

If and only if the media type is not specified by the Content-Type field, the recipient MAY try to guess the media type by checking its contents and / or the URI name extensions used to identify the resource.

but ... If you want to specify it, then saving the content type at boot time is a very good idea. It should be noted that django own documents say to check data from users

If you are on * unix, you can try to guess / check it:

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

(from How to find mime file type in python? )

0
source

Attaching the models.FileField file to an email in Django is nice and easy:

 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() 
+14
source

Another approach:

 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)) 
+4
source

I use django storages and so .path raises

 NotImplementedError: This backend doesn't support absolute paths.' 

To avoid this, I just open the file, read it, guess the mimetype and close it later all the time, using .attach instead of .attach_file magic.

 from mimetypes import guess_type from os.path import basename f = model.filefield f.open() msg.attach(basename(f.name), f.read(), guess_type(f.name)[0]) f.close() 
0
source

Source: https://habr.com/ru/post/891507/


All Articles