6

I'm trying to pass a custom upload_to function to my models imageField but I'd like to define the function as a model function....is that possible?

class MyModel(models.Model):
    ...
    image = models.ImageField(upload_to=self.get_image_path)
    ...

    def get_image_path(self, filename):
        ...
        return image_path

Now i know i can't reference it by 'self' since self doesn't exist at that point...is there a way to do this? If not - where is the best place to define that function?

Dan Hanly
  • 7,829
  • 13
  • 73
  • 134
9-bits
  • 10,395
  • 21
  • 61
  • 83
  • possible duplicate of [Django FileField with upload_to determined at runtime](http://stackoverflow.com/questions/1190697/django-filefield-with-upload-to-determined-at-runtime) – Paulo Scardine Feb 01 '12 at 08:10
  • Yeah, look at the link that Paulo mentions - it shows it clearly there (no `self.`, define the callable as a function in the models.py) – Steve Jalim Feb 01 '12 at 11:49
  • Looks like my answer is here after all: http://stackoverflow.com/questions/1190697/django-filefield-with-upload-to-determined-at-runtime – jduncan May 30 '12 at 03:29

2 Answers2

9

So Just remove "@classmethod" and Secator's code will work.

class MyModel(models.Model):

    # Need to be defined before the field    
    def get_image_path(self, filename): 
        # 'self' will work, because Django is explicitly passing it.
        return filename

    image = models.ImageField(upload_to=get_image_path)
Mixologist
  • 91
  • 1
  • 1
2

You can use staticmethod decorator to define the upload_to inside of a class (as a static method). Hovever it has no real benefit over typical solution, which is defining the get_image_path before class definition like here).

class MyModel(models.Model):

    # Need to be defined before the field
    @classmethod       
    def get_image_path(cls, filename): 
        # 'self' will work, because Django is explicitly passing it.
        return filename

    image = models.ImageField(upload_to=get_image_path)
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
  • 1
    @Secator: I tried this in my own code but it's not actually calling the method-- for the file location, I'm getting "Currently: /o7pDX.jpg" – Colleen Apr 26 '12 at 16:40
  • @Colleen, it's converting my staticmethod to a string too. Looks like the method has to be a direct attribute of the module (or of some module). – mjumbewu Jan 04 '13 at 23:09
  • it works find if you just define `get_image_path` as a normal method without `@classmethod` – laike9m Jan 10 '14 at 11:05
  • in a `@classmethod`, the first param should be the class not the object. To make it less confused, I think you should use `cls` instead of `self` – Nathan Do Feb 25 '19 at 04:47