views:

53

answers:

3

I want to call for a self function of a model class as such in upload_to:

class Foo(models.Model):
    filestack = models.FileField(upload_to=self. gen_save_path)

    def gen_save_path(self):
        """
        gen_save_path: void -> String
        Generates the path as a string for fileStack field.
        """
        return "some generated string"

However I am getting NameError: name 'self' is not defined error

A: 

I think this will work if you use a lambda function:

class Foo(models.Model):
    filestack = models.FileField(upload_to=lambda: self.gen_save_path())

    def gen_save_path(self):
        """
        gen_save_path: void -> String
        Generates the path as a string for fileStack field.
        """
        return "some generated string"
muksie
+1  A: 

in your code, the filestack is a class wide scope variable since not defined in a method. so there is no available self in this scope.

i think you can use :

filestack =models.FileField(upload_to=Foo.gen_save_path)

or

define filestack value within a __init__ constructor, where you can use self !!

dweeves
I think the last solution is the best one, define everything that is not class specific in the __init__ constructor
Ghislain Leveque
I like the first method here, but you will need to define `gen_save_path` as a classmethod if you do that.
Daniel Roseman
You can NOT access class name inside the class, Foo.gen_save_path will give error `Foo` not defined
Anurag Uniyal
+1  A: 

filestack is a class attribute and while declaring it you can not use self as there is no object of class (self) yet created, anyway according to django docs upload_to takes two arguments, instance(An instance of the model where the FileField is defined) and filename(The filename that was originally given to the file), so you can set upload_to to such function

def gen_save_path(instance, filename):
    """
    gen_save_path: void -> String
    Generates the path as a string for fileStack field.
    """
    return "some generated string"

class Foo(models.Model):

    filestack = models.FileField(upload_to=gen_save_path)

if you wish to include gen_save_path inside the class, you can sue lambda to call self.gen_save_path e.g.

class Foo(models.Model):

    filestack = models.FileField(upload_to=lambda self, fname:self.gen_save_path(fname))

    def gen_save_path(self, filename):
        return "some generated string"
Anurag Uniyal