Django-使用xhtml2pdf在模型中保存生成的PDF

问题描述

我正在尝试使用xhtml2pdf应用程序保存生成的PDF。我希望它将pdf保存到模型。完美地创建了pdf文件,浏览器下载了该文件,但我想将其保存到模型中,而不是下载,该模型在我的models.py中已告诉它保存到media文件夹中的文件夹中。>

Models.py:

class purchase(models.Model):
    purchase_id = models.AutoField(primary_key=True)
    transaction_date = models.DateTimeField()
    method_payment = models.CharField(max_length = 20)
    cmr_name = models.CharField(max_length = 60)
    cmr_address = models.CharField(max_length = 90)
    cmr_postcode = models.CharField(max_length = 10)
    cmr_tel = models.CharField(max_length = 14)
    cmr_email = models.CharField(max_length = 40)
    cmr_pod = models.FileField(upload_to='customers_id')
    cmr_signature = JSignatureField()
    receipt = models.FileField(upload_to='receipts',null=True,blank=True)
    added_by = models.CharField(max_length = 30)
    item_brand = models.CharField(max_length = 50)
    product = models.CharField(max_length = 100)
    model = models.CharField(max_length = 100)
    serial = models.CharField(max_length = 50)
    item_brand2 = models.CharField(max_length = 50)
    product2 = models.CharField(max_length = 100)
    model2 = models.CharField(max_length = 100)
    serial2 = models.CharField(max_length = 50)
    item_brand3 = models.CharField(max_length = 50)
    product3 = models.CharField(max_length = 100)
    model3 = models.CharField(max_length = 100)
    serial3 = models.CharField(max_length = 50)
    def __str__(self):
        return '{}'.format(self.cmr_name)

Utils.py:

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

views.py:

@login_required(login_url='/accounts/login/')
def add_purchase(request):
    username = None
    if request.user.is_authenticated:
        username = request.user.username
    viewing_info = pwl.objects.get(pk='1')
    viewing_ot = opening_times.objects.get(pk='1')
    viewing_brands = watch_brands.objects.all()
    viewing_watches = watch.objects.values_list('watch_brand_name',flat=True).distinct()
    template = loader.get_template('pwl-access/add_purchase.html')
    if request.method == 'POST':
        form = add_purchase_form(request.POST,request.FILES)
        if form.is_valid():
            ## Form Data
            transaction_date = str(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            added_by = request.user
            cmr_name = form.cleaned_data['cmr_name']
            cmr_address = form.cleaned_data['cmr_address']
            cmr_postcode = form.cleaned_data['cmr_postcode']
            cmr_tel = form.cleaned_data['cmr_tel']
            cmr_email = form.cleaned_data['cmr_email']
            purchase_price = form.cleaned_data['purchase_price']
            method_payment = form.cleaned_data['method_payment']
            item_brand = form.cleaned_data['item_brand']
            product = form.cleaned_data['product']
            model = form.cleaned_data['model']
            serial = form.cleaned_data['serial']
            price = form.cleaned_data['price']
            item_brand2 = form.cleaned_data['item_brand2']
            product2 = form.cleaned_data['product2']
            model2 = form.cleaned_data['model2']
            serial2 = form.cleaned_data['serial2']
            price2 = form.cleaned_data['price2']
            item_brand3 = form.cleaned_data['item_brand3']
            product3 = form.cleaned_data['product3']
            model3 = form.cleaned_data['model3']
            serial3 = form.cleaned_data['serial3']
            price3 = form.cleaned_data['price3']
            cmr_pod = request.FILES['cmr_pod'] if 'cmr_pod' in request.FILES else False
            cmr_signature = form.cleaned_data.get('cmr_signature')
            receipt = False
            if cmr_signature:
                signature_picture = draw_signature(cmr_signature,as_file=True)
            new_purchase = purchase(transaction_date=transaction_date,added_by=added_by,cmr_name=cmr_name,cmr_address=cmr_address,cmr_postcode=cmr_postcode,cmr_tel=cmr_tel,cmr_email=cmr_email,cmr_pod=cmr_pod,cmr_signature=signature_picture,receipt=receipt,method_payment=method_payment,item_brand=item_brand,product=product,model=model,serial=serial,item_brand2=item_brand2,product2=product2,model2=model2,serial2=serial2,item_brand3=item_brand3,product3=product3,model3=model3,serial3=serial3,)
            new_purchase.save()

            ##Receipt Creation
            cb_data = {
                'purchase_price': purchase_price,'price': price,'price2': price2,'price3': price3,'new_purchase': new_purchase,'cmr_pod': cmr_pod,'signature_picture': signature_picture,}
            template = get_template('pwl-access/email-templates/receipt_p_email.html')
            pdf = render_to_pdf('pwl-access/email-templates/receipt_p_pdf.html',cb_data)
            purch_id = new_purchase.pk
            if pdf:
                response = HttpResponse(pdf,content_type='application/pdf')
                filename = 'purchase_%s.pdf' % (purch_id)
                download = request.GET.get('download')
                content = "attachment; filename=%s " % (filename)
                response['Content-Disposition'] = content
                receipt_file = File(BytesIO(pdf.content))
                purchase.objects.filter(pk=purch_id).update(receipt=receipt_file)

            email_subject = 'Your Receipt from  - ' + transaction_date
            email_to = 'email'
            filled_email = template.render(cb_data)
            msg = EmailMultiAlternatives(email_subject,filled_email,'enquiries@.co.uk',[email_to],)
            msg.content_subtype = "html"

            if email_subject:
                try:
                    msg.send()
                except BadHeaderError:
                    return HttpResponse('Invalid header found.')
                messages.success(request,'Success! Purchase added and email has been sent to the customer ')
                return response
    else:
        form = add_purchase_form()

    context = {
        'viewing_info': viewing_info,'viewing_ot': viewing_ot,'viewing_brands': viewing_brands,'viewing_watches': viewing_watches,'form': form,}
    return HttpResponse(template.render(context,request))

管理员和数据库显示未上传任何内容,我没有收到任何错误。我希望在views.py文件中这些行代码可以用pdf文件更新数据库:

receipt_file = File(BytesIO(pdf.content))
purchase.objects.filter(pk=purch_id).update(receipt=receipt_file)

不幸的是,它什么也没做。有人可以帮忙吗?被困了一段时间。我已经尝试了在stackoverflow和其他网站上看到的其他几个答案。

感谢您的帮助。

编辑1: 我试图调用save()而不是update,但是没什么区别:

                receipt_file = File(BytesIO(pdf.content))
                purch = purchase.objects.get(pk=purch_id)
                purch.receipt = receipt_file
                purch.save()

Edit2:我还尝试了多个版本的content和IOString(content),但没有解决

Edit3:还是没有答案,任何可能知道正在发生什么的Django专家?看起来很简单。

解决方法

最后,我设法使用以下代码做到了这一点:

                receipt_file = BytesIO(pdf.content)
                purch_upd = purchase.objects.get(pk=purch_id)
                purch_upd.receipt = File(receipt_file,filename)
                purch_upd.save()

那么简单,简直无法相信这么久。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...