django - FileField 中的“upload_to”回调是否命中数据库以获取相关内容?
问题描述
我有一个Attachment
带有两个 ForeignKey 字段和属性get_attachment_path
回调的模型:upload_to
def get_attachment_path(instance, filename):
return f'{instance.owner.name}/{instance.chat.id}/{filename}'
class Attachment(models.Model):
owner = models.ForeignKey(..)
chat = models.ForeignKey(..)
file = models.FileField(upload_to=get_attachment_path, ...)
下面的行将导致get_attachment_path
运行:
Attachment.objects.create(..., file=file)
那么,使用上面的代码,django 会两次访问数据库(一次用于 the .create
,另一次用于get_attachment_path
)?询问它是因为get_attachment_path
回调尝试访问相关数据(instance.chat.id
等)。
如果是这样,有没有办法优化它?
解决方案
不,它不会命中数据库,因为您已经将现有和保存的(!)Owner
和Chat
对象传递给Attachment.objects.create
,因此上传处理程序不需要从数据库中获取它们。
但是,当您从数据库中获取新附件时,将对相关对象进行额外查询:
attachment = Attachment.objects.get(id=some_id)
attachment.file.save(...)
在这种情况下,使用select_related
可以删除额外的查询。
您始终可以验证正在运行的 SQL 查询(仅在DEBUG
模式下):
from django.db import connection
def get_attachment_path(instance, filename):
print('Queries before', connection.queries)
path = f'{instance.owner.name}/{instance.chat.id}/{filename}'
print('Queries after', connection.queries)
return path
或者,Django 调试工具栏是 Django 项目的一个很好的补充,可以优化 SQL 查询。
推荐阅读
- python - error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools" scrapy
- java - Java FileDialog browse and read from file
- android - GPS跟踪系统?
- python - 如何在python中获取属性的setter方法的属性
- c - 源路径中有空格时 VS Code 调试失败
- python - Any way to read number of active workers of gunicorn managed by the arbiter from command line?
- c++ - Access static variable from CPP file to other header file
- angular - Angular 2 Route Translation
- node.js - 'apidoc' is not recognized as an internal or external command
- kernel - 内核问题,试图解决触摸板问题