Home > Net >  Does the 'upload_to' callback in the FileField hit the db for related content?
Does the 'upload_to' callback in the FileField hit the db for related content?

Time:09-16

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.

  • Related