Opened 20 months ago

Closed 20 months ago

Last modified 20 months ago

#33993 closed New feature (needsinfo)

Allow instance to be passed into the FileField storage callable param

Reported by: Viicos Owned by: nobody
Component: File uploads/storage Version: dev
Severity: Normal Keywords: callable, storage, filefield
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Viicos)

A while ago #28184 introduced the ability to use callables as the storage parameter of the FileField.

Someone even requested the ability to have the instance passed into the callable: https://github.com/django/django/pull/8477/files#r226555624

But I believe @miigotu misinterpreted it and was thinking about a Storage instance.

What could be great is the ability to pass the instance (and maybe the filename too) similar to upload_to

Example:

def get_storage(instance, filename):
    if instance.is_private:
        return PrivateStorage()
    else:
        ...

This could allow the user to use a specific storage depending on the instance being saved.

Change History (4)

comment:1 by Viicos, 20 months ago

Description: modified (diff)

comment:2 by Carlton Gibson, 20 months ago

Resolution: needsinfo
Status: newclosed

This looks likely feasible for the generate_filename usage, but I can't see immediately whether there'd be issues with path and url and so on. (After file creation, we get the filename from the storage, so we'd need to handle not having that available.)

I'd like to say that if you can put together a proof-of-concept PR, that doesn't break anything, and isn't too complex then we can move forward, but I think seeing that would be good before just accepting.

Thanks!

in reply to:  2 comment:3 by Viicos, 20 months ago

Replying to Carlton Gibson:

This looks likely feasible for the generate_filename usage, but I can't see immediately whether there'd be issues with path and url and so on. (After file creation, we get the filename from the storage, so we'd need to handle not having that available.)

Isn't this already the case now, as you can use a callable to get the storage object? What I was suggesting is having the ability to pass the instance (and additionally the filename) to this callable.

comment:4 by Carlton Gibson, 20 months ago

Currently, the storage is instantiated at model definition time (when the field is instantiated as the model class definition is processed). There is no instance at that time. So, there would need to be on-access update (via a property, likely) to add the instance info. (How handling access without an instance would need to be looked at.)

The same goes for the filename. Is it always available? What complexities would need to be handled if not? 🤔

None of that's to say it couldn't work, but a proof-of-concept showing it would help.
I hope that makes sense.

Note: See TracTickets for help on using tickets.
Back to Top