2015-11-05 41 views
0

我有一个基类图片,在这里我设置的上传目录。 这与其应该完全相同。 因为,据我迄今读过的,它是不可能重写Django中父类的字段,我想我会尝试这种方式。覆盖硬编码值的Python的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" 

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

+0

那你想干什么?为“ActivityThumbnail”的每个实例指定一个不同的(不是基本类型)“upload_dir”值?或“ActivityThumbnail”的所有实例? – Kashyap

+0

@Kashyap在这一刻,我只是想将ActivityThumbnail的每个图像上传到同一个文件夹。我也有BackgroundImage和GeneralImage类,它们将获得自己的上传目录,但现在我只想对它们进行硬编码。 –

+0

你只改变了类属性的值'upload_directory' ......如果你'打印ActivityThumbnail.upload_directory'你会看到它有您设置的新值。你有没有做过是如果不是一个字符串传递一个可调用(即功能)改变'upload_to'路径上的'image'场 – Anentropic

回答

1

在你的情况,你应该使用函数来获取上传路径,包括文件名。

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

+0

作品链接的魅力。感谢很多@VongHoang –

0

你混合类变量和实例变量。

当你处理类变量(在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