在视图中的模型中保存文件有效,但在 Celery 任务中无效
Posted
技术标签:
【中文标题】在视图中的模型中保存文件有效,但在 Celery 任务中无效【英文标题】:Saving File in Model in View works but not in Celery Task 【发布时间】:2021-09-07 10:30:54 【问题描述】:我遇到了这种非常奇怪的行为,当我在视图中保存新模型实例时,分配的文件被保存,但是当我在 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 实例的生成方式)
实例将被保存(文档的路径也是正确的!没有抛出异常),但文件本身不会被保存。
我错过了什么??
【问题讨论】:
【参考方案1】:我发现了问题。整个应用程序在 Docker 环境中运行。 Django 应用程序和 Celery 已在单独的容器中运行。问题是 Celery 无法访问 Django 文件系统,因此文件被保存,但无法访问 Django 容器……非常愚蠢的错误,但我花了几天时间才弄清楚。因此,如果有人偶然发现同样的问题,请检查您的 docker 卷。
【讨论】:
以上是关于在视图中的模型中保存文件有效,但在 Celery 任务中无效的主要内容,如果未能解决你的问题,请参考以下文章
Django 模型没有保存到 Celery Task 中的数据库中
模型方法在 Bookings 模型中有效,但在事件和票证中无效