hzdg / django-modeltools

Enums in your models, template strings for FileField names…

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

format_filename Doesn't Work For Directories

matthewwithanm opened this issue · comments

Generally, Django "knows" whether your upload_to value is a full filename or just a directory. If it is a directory, the file will be saved in that location but with the original filename. However, format_filename appends the original extension automatically, so the result is never a path.

The method should be updated so as to allow directories. For example, _ff('{first_name}_{last_name}/') should place the uploaded file in a directory named using the interpolated values, with the same filename as the original file.

The easiest way to do this would be to check for a trailing slash, and not append the extension if present. However, I feel like there might be a better solution—one that doesn't re-determine what the framework is already determining (namely, whether you've specified a directory or filename).

FWIW, I just realized that Django only treats the upload_to value as a directory if it's a string—callables are always expected to return filenames. This make sense in their situation: since a string would remain the same for every file, it wouldn't make sense to use that as a filename. However our string (being a template) does change based on the file being saved, so the same assumption doesn't make sense.

We could just say "well, _ff returns a callable and callable upload_to values specify filenames and not directories," but—while that's true—I think it misses an opportunity to make things easier. Besides, the _ff function reads almost like a macro, and I think we should strive to make it behave that way.

On the other hand, we could expose the original filename to the string formatter. (This would probably mean that we do the same with extension—instead of automatically appending it as we do now—for consistency.) For example:

_ff('{first_name}_{last_name}/{_filename}.{_ext}')

I'm using an underscore here to indicate that these are special values and not properties of the model. (They could be differentiated other ways, but I suspect this would be the clearest, though it does prevent you from using "private" model properties.)

This would eliminate the need to differentiate between directories and filenames (by eliminating the ability to specify a directory) at the cost of requiring a more explicit format string.

In the case of

_ff('{first_name}_{last_name}/{_filename}')

would we just include the ext?