如何在Django Admin中的每个对象上使用可点击按钮生成PDF?

时间:2018-11-27 23:09:52

标签: django encoding io django-admin xhtml2pdf

问候强大的stackoverflow社区!

对于这种发票模型,我不理解如何在管理视图中以如下所述的方式在每个对象上创建具有可点击链接的列(也就是带有“生成pdf”链接的列)(def show_phone_url)。使用render方法生成PDF的每个对象。

由于这里有相关问题,我设法弄清楚了如何使用Invoice.objects.all()将模型的每个对象馈入html模板pdf.html,然后通过xhtml2pdf和io转换为PDF。

我能够手动输入单个对象的数据,放入Invoice.objects.get(pk = 1)并删除Jinja {% for invoice in invoices %} {% endfor %}

以前,我能够为admin中的每个对象创建一个带有可点击链接的列(对于不同的模型),该对象从对象属性中获取值。就是这样实现的:

from django.utils.html import format_html

    class SipAccountAdmin(admin.ModelAdmin):
        list_display = ('sip_no', 'show_phone_url')

    def show_phone_url(self, obj):
        return format_html("<a href='{url}'>{url}</a>", url=obj.sip_account_ip)
    show_phone_url.short_description = u'Web interface'

该概念是通过按“生成pdf”按钮以某种方式将对象的pk馈送到Pdf类参数,并获得带有数据的所需模板。

可能是该方法从根本上是不正确的,并且可以更优雅地完成任务。我先向您道歉,因为我是django的新手,并且正在编写代码,这是这里的第一篇文章...

我无休止地搜索网络后考虑了一些事情,即使我也不知道如何实现它们:

  • 创建自定义管理操作:选定对象->“生成PDF” 从动作下拉菜单中选择->动作会导致带有pdf的视图 填充了来自选定对象的数据
  • 创建Invoice对象并生成文件“填充”该对象的FileField后,便会立即形成pdf文件。

我在此先感谢任何可以提供帮助的人。

MODELS.PY

class Invoice(models.Model):
class Meta:
    verbose_name = 'Invoice'
    verbose_name_plural = 'Invoices'

invoice_number = models.BigIntegerField('Invoice number')
invoice_value = models.FloatField('Invoice value')
invoice_date = models.DateField('Date issued')

def __str__(self):
    return str(self.invoice_number)

@staticmethod
def render(path: str, params: dict):
    template = get_template(path)
    html = template.render(params)
    response = BytesIO()
    pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), response, encoding='utf-8')
    if not pdf.err:
        return HttpResponse(response.getvalue(), content_type='application/pdf')

    else:
        return HttpResponse("Error rendering", status=400)

VIEWS.PY

from invoicesystem.models import *


class Pdf(View):

    def get(self, request):
        invoices = Invoice.objects.all()

        params = {
            'invoices': invoices,
            'request': request
        }

        return Invoice.render('invoicesystem/render/pdf.html', params)

URLS.PY

path('render/pdf/', Pdf.as_view())

插入数据的HTML模板部分:

 <table class="table">
        <thead>
        <tr>
            <th>Number</th>
            <th>Date</th>
            <th>Value</th>
        </tr>
        </thead>
        <tbody>
        {% for invoice in invoices %}
            <tr>
                <td>{{ invoice.invoice_number }}</td>
                <td>{{ invoice.invoice_date }}</td>
                <td>{{ invoice.invoice_value }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
  

任何为生成的PDF(西里尔字母,阿拉伯字母等)的编码而苦苦挣扎的人的信息:

我发现了很多有关“黑色正方形”而不是符号的问题。

这些参数正确显示字符:

pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), response, encoding='utf-8')

不要忘记在模板中插入元标记:

<meta http-equiv=Content-Type content="text/html;charset=utf-8">

在带有路径的模板的内部样式中包括font-face和font-family;确保它可以访问,甚至可以为您选择的支持所需字符的ttf字体提供完整路径。我将我的放在项目的静态文件夹中,并使用了相对路径:

@font-face {
  font-family: "Ubuntu"; 
  src: url("project/static/font/Ubuntu/Ubuntu-R.ttf");}
 html,body {
   font-family: 'Ubuntu';
    }

0 个答案:

没有答案