python - upload_to dynamically generated url to callable -
i've seen lot of post problem without understanding how solve it.
i have model:
class project(timestampedmodel): name = models.textfield(max_length=100, default='no name') logo = models.imagefield() i'd have image saved media root following template:
<name>/logo/<filename> at first glance, do:
logo = models.imagefield(upload_to="{}/logo/".format(name))
but raises error: attributeerror: 'textfield' object has no attribute 'model'
using callable fine, partially though:
def upload_to_project(self, filename): url = ("%s/%s") % (self.name, filename) return url and using:
logo = models.imagefield(upload_to=upload_to_project) at least have: <name>/<filename>
but how pass argument in case? i'd reuse function upload in other subfolders, not logo as:
<name>/logo/<filename> <name>/history/<filename> <name>/whatever/<filename> any idea on do?
it looks (re-reading post it's not 100% clear) want partial application. news, it's part of python's stdlib:
import os functools import partial def generic_upload_to(instance, filename, folder): return os.path.join(instance.name, folder, filename) class project(timestampedmodel): name = models.textfield(max_length=100, default='no name') logo = models.imagefield( upload_to=partial(generic_upload_to, folder="logo") ) note implementation assumes instance has name attribute... if instance attribute want use first part has configurable can rewrite upload_to as:
def generic_upload_to(instance, filename, folder, attrname): return os.path.join(getattr(instance, attrname), folder, filename) then use as
class project(timestampedmodel): name = models.textfield(max_length=100, default='no name') logo = models.imagefield( upload_to=partial(generic_upload_to, attrname="name", folder="logo") ) and if have more 1 filefield or imagefield in model , don't want repeat attrname part:
class something(timestampedmodel): my_upload_to = partial(generic_upload_to, attrname="label") label = models.charfield(max_length=100, default='no label') logo = models.imagefield( upload_to=partial(my_upload_to, folder="logo") ) attachment = models.filefield( upload_to=partial(my_upload_to, folder="attachment") )
Comments
Post a Comment