Вложения в почте Django пустые, кроме первого отправленного письма, при переборе получателей
У меня есть информационный бюллетень, рассылаемый с помощью Django forms, с несколькими файлами, которые могут быть прикреплены.
Я прохожусь по списку получателей (если они проверены, согласились получать рассылку и т.д.)
.
Все работает нормально, письма приходят этим пользователям, включая 1 или более прикрепленных файлов.
Проблема в том, что только первый пользователь получает файлы\ с содержимым, остальные получают файлы, но они пустые/пустые (ноль байт).
Связано ли это с какими-то временными файлами или необходимо сначала кэшировать эти файлы, чтобы они были доступны для обработки циклом?
(примечание: имя файла, количество файлов и т.д., полученные всеми получателями, все правильно - они просто пусты, кроме первого письма)
.
Как я могу решить эту проблему? Спасибо
forms.py
class NewsletterForm(forms.Form):
message = forms.CharField(widget = forms.Textarea, max_length = 8000)
attach = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}), required=False)
views.py
def newsletter(request):
users = User.objects.all()
receipient_list = []
for user in users:
if user.profile.newsletter_agree == True and user.profile.verified_member == True:
receipient_list.append(user.email)
if request.method == 'POST':
form = NewsletterForm(request.POST, request.FILES)
if form.is_valid():
mail_subject = 'Some newsletter subject'
message = form.cleaned_data['message'],
files = request.FILES.getlist('attach')
for contact_name in receipient_list:
try:
email = EmailMessage(mail_subject, message, 'email@email.com', to=[contact_name])
email.encoding = 'utf-8'
for f in files:
email.attach(f.name, f.read(), f.content_type)
email.send()
except BadHeaderError:
return HttpResponse('Invalid header found.')
messages.success(request, f'Newsletter sent successfully')
return redirect('main_page')
form = NewsletterForm()
context = {'form':form}
return render(request, 'my_app/newsletter.html', context)
newsletter.html
<form method="POST" enctype="multipart/form-data">
<fieldset class="form-group">
{% csrf_token %}
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-light">Send</button>
</div>
</form>
Функция чтения файла: f.read() читает файл и возвращает его в виде строки, но оставляет курсор чтения в конце файла. Поэтому, когда вы вызываете ее во второй раз, она ничего не возвращает.
В качестве варианта можно использовать attach_file вместо attach:
email.attach_file(f.name, f.content_type)
или прочитать каждый файл один раз, создать список тройников вложений и повторно использовать этот список.
files = request.FILES.getlist('attach')
attachments = []
for f in files:
attachments.append((f.name, f.read(), f.content_type))
for contact_name in receipient_list:
try:
email = EmailMessage(mail_subject, message, 'email@email.com', to=[contact_name], attachments=attachments)
email.encoding = 'utf-8'
email.send()