Ich erstelle eine Seite für Studentenregistrierungen mit dem Django-Framework.
Ich bin an einem Ort angekommen, an dem ich dem Benutzer das Formular anzeigen muss und die nach der Behandlung eingegebenen Informationen erhalte. Ich muss dem Benutzer eine E-Mail mit den von ihm eingegebenen Informationen senden, indem ich sie in ein PDF einfüge, das ich generieren muss aus einer Vorlage, die das Kontextwörterbuch enthält.
Im Moment ist das PDF, das ich generieren kann, nur möglich, indem ich es über die Funktion an den Browser sende. HttpResponse
Das Problem dabei ist jedoch, dass der Benutzer entscheidet, ob er es herunterlädt oder nicht, und ich mehr Möglichkeiten habe, die Hand aufzulegen das pdf, um es als anhang zu senden.
Ich dachte, ich würde eine Datenbank öffnen, in der es ein Feld vom Typ geben wird models.FileField
, das PDF mit dem Kontextwörterbuch über die Bibliothek generieren, das xhtml2pdf
ich mit einem Signal in der Datenbank speichern könnte, und dann die E-Mail senden, indem ich die Datei als Anhang nehme.
Keine der Methoden, die ich versucht habe, um dies zu erreichen, ist im Moment erfolgreich. Hier ist mein Code:
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type="application/pdf")
return None
from django.conf import settings
from django.db.models.signals import pre_save, post_save
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.db import models
# Create your models here.
class MyModel(models.Model):
order_id = models.CharField(max_length=255)
nom = models.CharField(max_length=255)
email = models.EmailField()
pdf = models.FileField(upload_to="pdfs", null=True, blank=True)
def create_order_id(instance, new_order_id=None):
order_id = instance.id
if new_order_id is not None:
order_id = new_order_id
qs = MyModel.objects.filter(order_id=order_id)
exists = qs.exists()
if exists:
new_order_id = "%s-%s" %(order_id.first().id)
return create_order_id(instance, new_order_id)
return order_id
def pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.order_id :
instance.new_order_id = create_order_id(instance)
def send_mail_insciption(instance):
subject = "Thank you"
from_email = settings.EMAIL_HOST_USER
to_email = [instance.email]
body = "Votre inscription"
email_pdf = EmailMultiAlternatives(
subject = subject,
body =body,
from_email = from_email,
to=to_email,
)
email_pdf.attach_alternative(instance.pdf, "application/pdf")
email_pdf.send()
def post_save_receiver(sender, instance, *args, **kwargs):
send_mail_insciption(instance)
pre_save.connect(pre_save_receiver, sender=MyModel )
post_save.connect(post_save_receiver, sender=MyModel)
#views.py
def pdf_genarete(request):
form = MyModelForm(request.POST or None)
if form.is_valid():
nom = form.cleaned_data.get("nom")
email = form.cleaned_data.get("email")
obj = MyModel.objects.create(nom=nom, email=email)
context = {"models_instance": obj}
pdf = render_to_pdf("pdfapp/template_pdf.html", context)
filename = "mypdf_{}.pdf".format(obj.order_id)
pdf.save()
obj.pdf.save(filename, File(BytesIO(pdf.content)))
return redirect(reverse("home"))
return render(request, "pdfapp/formulaire.html", {"form": form})
Nach der Ausführung ist hier der Fehler auf dem Terminal:
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/db/models/base.py", line 769, in save_base
update_fields=update_fields, raw=raw, using=using,
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 178, in send
for receiver in self._live_receivers(sender)
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 178, in <listcomp>
for receiver in self._live_receivers(sender)
File "/home/michel/saintexupery/saintexupry/pdfapp/models.py", line 69, in post_save_receiver
send_mail_insciption(instance)
File "/home/michel/saintexupery/saintexupry/pdfapp/models.py", line 65, in send_mail_insciption
email_pdf.send()
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/message.py", line 294, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/backends/smtp.py", line 110, in send_messages
sent = self._send(message)
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/backends/smtp.py", line 124, in _send
message = email_message.message()
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/message.py", line 254, in message
msg = self._create_message(msg)
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/message.py", line 440, in _create_message
return self._create_attachments(self._create_alternatives(msg))
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/message.py", line 450, in _create_alternatives
msg.attach(self._create_mime_attachment(*alternative))
File "/home/michel/saintexupery/env/lib/python3.6/site-packages/django/core/mail/message.py", line 393, in _create_mime_attachment
Encoders.encode_base64(attachment)
File "/usr/lib/python3.6/email/encoders.py", line 32, in encode_base64
encdata = str(_bencode(orig), 'ascii')
File "/home/michel/saintexupery/env/lib/python3.6/base64.py", line 534, in encodebytes
_input_type_check(s)
File "/home/michel/saintexupery/env/lib/python3.6/base64.py", line 520, in _input_type_check
raise TypeError(msg) from err
TypeError: expected bytes-like object, not FieldFile
Ich dein Code du hast diesen Teil:
def send_mail_insciption(instance):
...
email_pdf.attach_alternative(instance.pdf, "application/pdf")
email_pdf.send()
Die Fehlermeldung (und das Traceback) besagen, dass die E-Mail Bytes als Anhang erwartet, aber a instance.pdf
ist FieldFile
.
Versuchen Sie, die Datei in Bytes zu konvertieren, verwenden Sie sie möglicherweise instance.pdf.read()
und lassen Sie uns wissen, ob das Problem dadurch behoben wird.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen