我遇到了这种非常奇怪的行为,当我在视图中保存新的模型实例时,分配的文件会被保存,但是当我在 Celery 中这样做时,实例会被保存,但文件不会被保存。
这些是我的观点(缩短):
def post(self, request, *args, **kwargs):
[...]
html = render_to_string('pdf/w_html.html', {'request': self.object})
out = BytesIO()
HTML(string=html).write_pdf(out, stylesheets=[CSS(settings.STATIC_ROOT + "/css/pdf.css"),
'https://fonts.googleapis.com/css2?family=Montserrat&family=Playfair+Display&display=swap'])
document = Document(product=product, document_type=4,
language=1, date=timezone.now().date(),
file=File(out, name='Best_Execution_Report.pdf'))
document.save()
其中 self.object 是 Request 实例。
上面的代码完全完成了它应该做的事情(即保存模型和生成的 pdf)。
但是一旦我将上面的代码修改为这样:
def post(self, request, *args, **kwargs):
[...]
generate_best_execution_report.apply_async(kwargs={'request_id': self.object.pk})
执行以下 celery 任务:
@shared_task
def generate_best_execution_report(request_id):
"""Task to automatically generate best execution Reports and save it to the Documents Model (of the product app)."""
request_obj = Request.objects.get(pk=request_id)
logger.info(request_obj)
html = render_to_string('pdf/w_html.html', {'request': request_obj})
logger.info(html)
out = BytesIO()
HTML(string=html).write_pdf(out,
stylesheets=[
CSS(settings.STATIC_ROOT + "/css/pdf.css"),
'https://fonts.googleapis.com/css2?family=Montserrat&family=Playfair+Display&display=swap'
]
)
logger.info(out)
with transaction.atomic():
document = Document(product=request_obj.product, document_type=4,
language=1, date=timezone.now().date(),
file=File(out, name='Best_Execution_Report.pdf'))
try:
document.save()
except Exception as e:
logger.info(e)
logger.info(document)
return True
(请注意,请求是产品上的一对一关系,因此我必须稍微更改 Document 实例的生成方式)
实例将被保存(文档的路径也是正确的!不会引发异常),但文件本身不会被保存。
我缺少什么?