django 如何使用celery和dajngo发送带有图像附加的电子邮件?

q8l4jmvw  于 2023-04-13  发布在  Go
关注(0)|答案(1)|浏览(154)

我想用celery发送一封带有照片的电子邮件,但我得到了“Object of type bytes is not JSON serializable”错误。我只是不知道如何正确地做到这一点。据我所知,celery不支持字节。但我试图将其转换为字符串,并得到其他错误。

views.py

from main_app.tasks import send_creator_submission_email_task

class BecomeCreatorView(TemplateView):
    template_name = 'become_creator.html'
    become_creator_form = BecomeCreatorForm
    success_url = reverse_lazy('index')

    def get(self, request, *args, **kwargs):
        form = self.become_creator_form()
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.become_creator_form(request.POST, request.FILES)
        if form.is_valid():
            photo = form.cleaned_data['photo']
            send_creator_submission_email_task.delay(self.kwargs.get('slug'), photo.file, photo.name)
            messages.success(request, "Thank you!")
            return redirect(self.success_url)
        messages.error(request, "Error!")
        return render(request, self.template_name, {'form': form})

任务.py

@shared_task
def send_creator_submission_email_task(slug, image_file, image_filename):
    return send_creator_submission_email(slug, image_file, image_filename)

email.py

def send_creator_submission_email(slug, image_file, image_filename):
    user = get_object_or_404(User, slug=slug)
    current_site = Site.objects.get_current().domain

    email_context = {
        'current_site': current_site,
        'user_email': user.email,
        'user_slug': user.slug,
        'approve_url': f"http://{current_site}{reverse_lazy('approve_user', kwargs={'slug': user.slug})}",
        "decline_url": f"http://{current_site}{reverse_lazy('decline_user', kwargs={'slug': user.slug})}"
    }

    html_message = render_to_string('email/admin_decision_email.html', email_context)
    plain_message = strip_tags(html_message)

    email = EmailMultiAlternatives(
        subject="New creator submission",
        body=plain_message,
        from_email=settings.DEFAULT_FROM_EMAIL,
        to=[settings.EMAIL_ADMIN],
    )

    email.attach_alternative(html_message, "text/html")
    email.attach(image_filename, image_file.read())
    email.send()

如果你想重新创建案例,这些文件是为你准备的:forms.py

class BecomeCreatorForm(forms.Form):
    photo = forms.ImageField(
        required=True,
        widget=forms.ClearableFileInput
    )

admin_decision_email.html

{% autoescape off %}

<p>New user photo submission from: {{ user_email }}</p>
<p>User slug: {{ user_slug }}</p>
<p>Please approve or decline the attached photo.</p>

<p>Actevate: {{ approve_url }}</p>
<p>Decline: {{ decline_url }}</p>

{% endautoescape %}
d7v8vwbk

d7v8vwbk1#

所以,我自己解决了,我会把答案留给后人。

import base64

对视图中的图像进行编码并将其传递给celery函数。

if form.is_valid():
    photo_data = form.cleaned_data['photo'].read()
    photo_name = form.cleaned_data['photo'].name
    photo_data_base64 = base64.b64encode(photo_data).decode()
    send_creator_submission_email_task.delay(self.kwargs.get('slug'), photo_data_base64, photo_name)
    messages.success(request, "Thank you!")
    return redirect(self.success_url)

在celery函数中解码并附加到电子邮件中:

photo_data = base64.b64decode(attachment_data)
email.attach(attachment_name, photo_data)

就是这样!

相关问题