繁体   English   中英

覆盖硬编码值Python Django类

[英]Override hardcoded value Python Django class

我有一个基类Image,在其中设置了上载目录。 这完全可以正常工作。 由于到目前为止,就我所知,不可能覆盖Django中父类的字段,所以我想我会尝试这种方式。

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

但是,当在子类中覆盖upload_directory时,这根本没有结果。 现在,图像仍上传到父类中设置的目录中。

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

为每个子类设置上传目录路径的正确方法是什么?

对于您的情况,应该使用函数来获取上载路径,包括文件名。

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"

看看这个https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.FileField.upload_to

您正在混合类变量和实例变量。

在处理类变量 (与Java和C ++中的静态变量等效)时,应始终使用<class-name>.<variable-name>约定对其进行访问。 尽管使用实例名称访问它是合法的。

这样做使您意识到不需要为每个实例设置新的upload_dir,因此您可以在流/循环之外进行更多全局初始化。

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__

打印:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM