Нужно корректное имя файла! xhtml2pdf с Джанго

Моя проблема: я создаю файл PDF из HTML, используя библиотеку xhtml2pdf. Создав pdf-файл, я отправляю файл пользователю по электронной почте с помощью API sendgrid. Однако я не могу оставить изображение, встроенное в файл PDF, так как приложение возвращает мне «Нужно действительное имя файла!» Сообщение. Я исследовал в нескольких местах, но я не могу найти решение. Используемый код приведен ниже.

HTML-код:

<img src="/static/media/logo.jpg" alt="Image">

код python (конвертировать html в pdf):

def link_callback(uri, rel):
"""
Convert HTML URIs to absolute system paths so xhtml2pdf can access those
resources
"""
# use short variable names
sUrl = settings.STATIC_URL
mUrl = settings.MEDIA_URL
mRoot = settings.MEDIA_ROOT

# convert URIs to absolute system paths
if uri.startswith(mUrl):
    path = os.path.join(mRoot, uri.replace(mUrl, ""))

else:
    return uri  # handle absolute uri (ie: http://some.tld/foo.png)

# make sure that file exists
if not os.path.isfile(path):
        raise Exception(
            'media URI must start with %s or %s' % (sUrl, mUrl)
        )
return path

def render_to_pdf(template_source, context_dict={}):
    from io import BytesIO
    from django.http import HttpResponse
    from django.template.loader import get_template
    from xhtml2pdf import pisa

    template = get_template(template_source)
    html = template.render(context_dict)
    result = BytesIO()
    pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result, 
                        link_callback=link_callback, encoding='UTF-8')

    if not pdf.err:
        return result.getvalue()
    return None

код Python (отправить файл PDF по электронной почте):

def send_mail_template(subject, template_name, context, recipient_list, from_email=<email>, attachments=None):

sg = sendgrid.SendGridAPIClient(apikey=<apikey>)
sendgrid_from_email = Email(email=from_email, name=<name>)
message_html = render_to_string(template_name, context)
content = Content("text/html", message_html)

sendgrid_to_email = Email(recipient_list[0])
mail = Mail(sendgrid_from_email, subject, sendgrid_to_email, content)

try:
    if attachments is not None:
        for attachment in attachments:
            sendgrid_attachment = Attachment()
            sendgrid_attachment.content = base64.b64encode(attachment['file']).decode()
            sendgrid_attachment.content_id = attachment['filename']
            sendgrid_attachment.type = attachment['type']
            sendgrid_attachment.filename = attachment['filename']
            sendgrid_attachment.disposition = attachment['disposition']

            mail.add_attachment(sendgrid_attachment)
except Exception as err:
    print(err)

response = sg.client.mail.send.post(request_body=mail.get())

return response.status_code

Ошибка:

Need a valid file name!
'<img alt="Image" src="/static/media/logo.jpg"/>'

person Eli    schedule 19.12.2018    source источник
comment
Когда-то у меня также была такая же проблема, что сработало для меня, так это размещение полного пути к статическим изображениям или загрузка в какое-то ведро и размещение URL-адреса. если вы не найдете никакого решения, вы можете попробовать это.   -  person Sergey Pugach    schedule 19.12.2018
comment
Спасибо @SergeyPugach. Я указал полный путь и все заработало! Но если кто-то знает, как получить изображение с относительным путем, мне будет лучше.   -  person Eli    schedule 19.12.2018
comment
@SergeyPugach, пожалуйста, добавьте свой комментарий в качестве ответа - он решил проблему, с которой я сталкивался в течение двух дней !!   -  person Jesuisme    schedule 11.03.2019
comment
@Jesuisme Я разместил это как ответ.   -  person Sergey Pugach    schedule 12.03.2019


Ответы (1)


Похоже, что у xhtml2pdf есть проблемы с рендерингом изображений, лежащих рядом с шаблоном. Чтобы решить эту проблему, вы можете попробовать:

  1. Поместите полный путь к статическим изображениям, например
  2. Загрузите свое изображение в какое-нибудь ведро и укажите полный URL-адрес в src.
person Sergey Pugach    schedule 12.03.2019
comment
Если ведро s3 является частным, то как я могу получить доступ к образу? - person yasir kk; 01.10.2019