I have an Attachment
model with two ForeignKey fields and a get_attachment_path
callback for the upload_to
attribute:
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, ...)
Below line will cause the get_attachment_path
run:
Attachment.objects.create(..., file=file)
So, with the line above, will django hit the db twice (one for the .create
and one another for the get_attachment_path
)? Asking it because the get_attachment_path
callback tries to access related data (instance.chat.id
etc.).
If so, is there a way to optimize it?
CodePudding user response:
No, it will not hit the DB, because you're already passing existing and saved(!) Owner
and Chat
objects to Attachment.objects.create
, so the upload handler does not need to fetch them from the database.
However, extra queries for related objects will be made when you get the attachment fresh from the database:
attachment = Attachment.objects.get(id=some_id)
attachment.file.save(...)
In this case using select_related
can remove the extra queries.
You can always verify the SQL queries that are run (only in DEBUG
mode):
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
Alternatively, Django Debug Toolbar is a great addition to a Django project to optimize SQL queries.