[Fixed]-Override hardcoded value Python Django class

1👍

In your case, you should use function to obtain the upload path, including the filename.

def upload_to_path(instance, filename):
    return '{upload_dir}/{filename}'.format(
        upload_dir=instance.upload_dir,
        filename=filename
    )

class Image(models.Model):
    """
    Images base class
    """
    upload_dir = "uploads/images"
    image = models.ImageField(upload_to=upload_to_path)


class ActivityThumbnail(Image):
    """
    Thumbnail images for activities
    """
    upload_dir = "uploads/images/thumbnails/activities"

Take a look at this https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.FileField.upload_to

0👍

You are mixing class variables and instance variables.

When you’re dealing with a class variable (equivalent of a static variable in Java and C++), you should always access it using <class-name>.<variable-name> convention. Although it’s legal to access it using the instance name.

Doing this makes you realize that you don’t need to set the new upload_dir for every instance, hence you do it outside that flow/loop, at some more global initialization.

class base:
    var1 = 'from base'

    # can do without this
    @classmethod
    def set_var1(cls, v):
        cls.var1 = v


print 'before derived definitions: base.var1', base.var1

# wrong..
class derived1(base):
    # This is a different variable (FQDN: derived1.var1), it DOES NOT override the base.var1
    var1 = 'from derived1'

print 'after derived1 definition: base.var1', base.var1

# correct..
class derived2(base):
    # don't create a new variable derived2.var1
    pass

b = base()
d1 = derived1()
d2 = derived2()

base.var1 = 'overridden from main'

print '\nbase.var1', base.var1, 'b.var1', b.var1
print 'derived1.var1', derived1.var1, 'd1.var1', d1.var1
print 'derived2.var1', derived2.var1, 'd2.var1', d2.var1

# if you want to complicate things and make it look like you know $#!T
# create a classmethod, annotated appropriately to set the new value
base.set_var1('overridden from main 2')
print '\nbase.var1', base.var1, 'b.var1', b.var1
print 'derived1.var1', derived1.var1, 'd1.var1', d1.var1
print 'derived2.var1', derived2.var1, 'd2.var1', d2.var1


# if you REALLY wanna complicate things, e.g. because you have no control over
# code in base.py then you should be able to use the python RTTI functions and
# hack your way to set teh value on appropriate cls object using __set_attribute__

this prints:

before derived definitions: base.var1 from base
after derived1 definition: base.var1 from base

base.var1 overridden from main b.var1 overridden from main
derived1.var1 from derived1 d1.var1 from derived1
derived2.var1 overridden from main d2.var1 overridden from main

base.var1 overridden from main 2 b.var1 overridden from main 2
derived1.var1 from derived1 d1.var1 from derived1
derived2.var1 overridden from main 2 d2.var1 overridden from main 2

Leave a comment