模型继承和多态性问题

1 投票
3 回答
873 浏览
提问于 2025-04-16 03:53

我遇到了一个新的Django问题。情况是这样的:我有一个模型类叫做UploadItemModel,我在这个基础上创建了可以上传的项目,比如视频、音频文件等等。

class UploadItem(UserEntryModel):
    category = 'abstract item'
    file = models.FileField(upload_to=get_upload_directory) 

我这样来创建子类:

class Video(UploadItem):
    category = 'video'

我需要从一个自定义标签中访问类别属性。问题是,即使这个类实际上是视频,我得到的类别却是'abstract item'。

有没有什么线索?

补充说明:我需要使用层次结构,因为用户可以上传几种不同类型的项目(视频、音频文件、PDF文本)。我需要为每种类型创建一个类,但这些类之间有很多共同的地方(比如表单)。

3 个回答

0

你可以试着重写这个类的 __init__ 方法,为每个实例指定一个 category 吗?比如说:

class Video(UploadItem):
    def __init__(self, *args, **kwargs):
        super(Video, self).__init__(*args, **kwargs)
        self.category = 'video'
1

你需要创建一个额外的字段,用来描述那种类型。

这里有一个不错的教程,可以看看,它讲解了如何在Django模型中使用继承。

1

有什么线索吗?

有的。根据我所知道的,它并不像你想的那样工作。Django模型并不是简单的Python类。它们更像是元类,能够创建一种“隐藏”的类定义的实例。是的,预期的模型类确实存在,但它并不是你想象中的那样。首先,你使用的类是根据你的类定义为你构建的。这就是为什么在Django模型中,一些Python类的静态特性并不会像你预期的那样工作。

你实际上不能像这样使用类级别的项目。

你可能想要创建一个实际的字段,并设置一个默认值或者类似的东西。

class UploadItem(UserEntryModel):
    category = models.CharFIeld( default='abstract item' )
    file = models.FileField(upload_to=get_upload_directory) 

即使在问题中添加了评论,我仍然不太明白这样做的原因。似乎没有任何结构或行为上的区别。这些看起来都是同一类对象。子类似乎并没有定义任何新的东西。

选项。

  1. 直接使用类名,而不是在类级别使用这个“类别”项目。让类名足够好,这样你就不需要这个“类别”项目了。

  2. 使用一个属性

    class UploadItem(UserEntryModel):
        file = models.FileField(upload_to=get_upload_directory) 
        @property
        def category( self ):
            return self.__class__.__name__
    

撰写回答