在视图中的模型中保存文件有效但在 Celery 任务中无效
Saving File in Model in View works but not in Celery Task
我遇到了这种非常奇怪的行为,当我在我的视图中保存一个新的模型实例时,分配的文件被保存,但是当我在 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})
使用以下芹菜任务:
@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
(请注意,request 与产品是一对一的关系,因此我必须稍微更改 Document 实例的生成方式)
实例将被保存(文档的路径也是正确的!不会抛出异常)但文件本身不会被保存。
我错过了什么??
我发现了问题。整个应用程序在 Docker 环境中 运行ning。 Django 应用程序和 Celery 运行 在不同的容器中。问题是 Celery 没有访问 Django 文件系统的权限,所以文件被保存了,但是 Django 容器无法访问...非常愚蠢的错误,但我花了几天时间才弄清楚。因此,如果有人遇到同样的问题,请检查您的 docker 卷。
我遇到了这种非常奇怪的行为,当我在我的视图中保存一个新的模型实例时,分配的文件被保存,但是当我在 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})
使用以下芹菜任务:
@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
(请注意,request 与产品是一对一的关系,因此我必须稍微更改 Document 实例的生成方式)
实例将被保存(文档的路径也是正确的!不会抛出异常)但文件本身不会被保存。
我错过了什么??
我发现了问题。整个应用程序在 Docker 环境中 运行ning。 Django 应用程序和 Celery 运行 在不同的容器中。问题是 Celery 没有访问 Django 文件系统的权限,所以文件被保存了,但是 Django 容器无法访问...非常愚蠢的错误,但我花了几天时间才弄清楚。因此,如果有人遇到同样的问题,请检查您的 docker 卷。