使用 ReportLab 创建 PDF 然后将其保存到用户模型
Using ReportLab To Create A PDF Then Save It To A User Model
几天来我一直在努力让它工作,虽然我认为我已经接近了,但我仍然没有让它工作。
我有一个使用 ReportLab 生成 SimpleDocTemplate pdf 的函数,我想 return 它到调用视图,这样我就可以将它保存到 uesrs 配置文件模型。
到目前为止,这是我的代码:
model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pdf = models.FileField(upload_to='pdfs/user_pdfs')
错误信息:
'HttpResponse' object has no attribute 'read'
查看
def final_question(request):
if request.method == 'POST':
# this is the final form they complete
form = FinalQuestionForm(request.POST, request.FILES, instance=request.user.finalquestion)
if form.is_valid():
form.save()
# generate pdf containing all answers to enrolment questions
users_pdf = utils.generate_user_pdf(request)
# here i get the users model
# hard coded user_id for testing
users_profile = Profile.objects.get(user_id=1)
# then i get the field I want to save to
pdf = users_profile.profile_pdf
# then i save the generated pdf to the field
pdf.save('user_1_pdf', users_pdf)
我的pdf生成功能
def generate_user_pdf(request):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename = "test.pdf"'
doc = SimpleDocTemplate(response)
elements = []
data= [
['---TEST DATA---'],
['test data'],
]
[.. cont ..]
doc.build(elements)
return response
谢谢。
--编辑--
错误:
argument should be a bytes-like object or ASCII string, not 'FileResponse'
工具:
def generate_pdf(request):
buffer = io.BytesIO()
doc = SimpleDocTemplate('test')
story = []
doc.build(story)
response = FileResponse(buffer.getvalue())
return response
views.py
# generate pdf containing all answers
user_pdf = utils.generate_pdf(request)
# get users enrolment_pdf field
# temp hard-coded
user_profile = Profile.objects.get(user_id=1)
field = user_profile.user_pdf
# save the generated pdf to the user in the database
file_data = ContentFile(base64.b64decode(user_pdf))
field.save('test', file_data)
谢谢
首先,there is一个答案。
除了这个答案之外,您还需要阅读 this,只需使用 buffer.getvalue()
字节数组并使用 ContentFile
class 将其保存到模型字段。
要简化响应对象的工作,请使用 FileResponse。
--编辑--
您需要将您的pdf写入缓冲区:
doc = SimpleDocTemplate(buffer)
doc.build(story)
buffer.seek(0)
pdf: bytes = buffer.getvalue()
return FileResponse(pdf, filename='doc.pdf')
而且,我在文档中找到了 these 说明。
要将 pdf 保存到 Profile
:
file_data = ContentFile(pdf)
profile = Profile.objects.get(...)
profile.pdf_field.save('filename.pdf', file_data, save=False)
profile.save()
几天来我一直在努力让它工作,虽然我认为我已经接近了,但我仍然没有让它工作。
我有一个使用 ReportLab 生成 SimpleDocTemplate pdf 的函数,我想 return 它到调用视图,这样我就可以将它保存到 uesrs 配置文件模型。
到目前为止,这是我的代码:
model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pdf = models.FileField(upload_to='pdfs/user_pdfs')
错误信息:
'HttpResponse' object has no attribute 'read'
查看
def final_question(request):
if request.method == 'POST':
# this is the final form they complete
form = FinalQuestionForm(request.POST, request.FILES, instance=request.user.finalquestion)
if form.is_valid():
form.save()
# generate pdf containing all answers to enrolment questions
users_pdf = utils.generate_user_pdf(request)
# here i get the users model
# hard coded user_id for testing
users_profile = Profile.objects.get(user_id=1)
# then i get the field I want to save to
pdf = users_profile.profile_pdf
# then i save the generated pdf to the field
pdf.save('user_1_pdf', users_pdf)
我的pdf生成功能
def generate_user_pdf(request):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename = "test.pdf"'
doc = SimpleDocTemplate(response)
elements = []
data= [
['---TEST DATA---'],
['test data'],
]
[.. cont ..]
doc.build(elements)
return response
谢谢。
--编辑--
错误:
argument should be a bytes-like object or ASCII string, not 'FileResponse'
工具:
def generate_pdf(request):
buffer = io.BytesIO()
doc = SimpleDocTemplate('test')
story = []
doc.build(story)
response = FileResponse(buffer.getvalue())
return response
views.py
# generate pdf containing all answers
user_pdf = utils.generate_pdf(request)
# get users enrolment_pdf field
# temp hard-coded
user_profile = Profile.objects.get(user_id=1)
field = user_profile.user_pdf
# save the generated pdf to the user in the database
file_data = ContentFile(base64.b64decode(user_pdf))
field.save('test', file_data)
谢谢
首先,there is一个答案。
除了这个答案之外,您还需要阅读 this,只需使用 buffer.getvalue()
字节数组并使用 ContentFile
class 将其保存到模型字段。
要简化响应对象的工作,请使用 FileResponse。
--编辑--
您需要将您的pdf写入缓冲区:
doc = SimpleDocTemplate(buffer)
doc.build(story)
buffer.seek(0)
pdf: bytes = buffer.getvalue()
return FileResponse(pdf, filename='doc.pdf')
而且,我在文档中找到了 these 说明。
要将 pdf 保存到 Profile
:
file_data = ContentFile(pdf)
profile = Profile.objects.get(...)
profile.pdf_field.save('filename.pdf', file_data, save=False)
profile.save()