Q:

django - set the upload_to in the view

I have a model for storing files:
class AFile(models.Model):
    path = models.CharField(max_length=256)
    name = models.CharField(max_length=256)
    file = models.FileField(upload_to=get_path)

there are many views that save files. I want a seperate path for each. so I put path in the model and use that in the get path function. like so:
afile = AFile(path='blah/foo/', name='filex.jpg')
afile.save()

so the file is in the right spot. But I don't really want to store the path and name field in my database, its only there to generate a path. any way to achieve this same thing without extra model fields?

A:

The problem here is that upload_to is only available when defining the FileField or ImageField on the model. Any subsequent access to the field returns a FieldFile instance, which doesn't have access to the defined upload_to. Long and short, there's no way to alter the method after it's initially defined.
However, you might be able to do a sort of end-run around it. Note that I haven't actually tried this, but it should work:
First define a method on your model that will have the simple task of setting an instance variable on the model:
def set_upload_to_info(self, path, name):
    self.upload_to_info = (path, name)

Then, inside your upload_to method, you can test for the presence of these attributes and use them if they are:
def my_upload_to(instance, filename):
    if hasattr(instance, 'upload_to_info'):
        path, name = instance.upload_to_info
        # do something and return file path
    else:
        # standard upload_to bit here

Then in your view, you just need to call the method you create before you save the model:
afile.set_upload_to_info(path, name)
afile.save()

