maroxe
maroxe

Reputation: 2127

Problem with model inheritance and polymorphism

i came with new django problem. The situtaion: i have a model class UploadItemModel, i subcallss it to create uploadable items, like videos, audio files ...

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

i subclass it like this:

class Video(UploadItem):
    category = 'video'

I need to access category attributes from a custom tag. The problem si that i am getting category='abstract item' even if the class is actually Video.

Any clue?

EDIT: I need to use hierarchy because i have several types of item that user can uplaod(Video, Audio files, PDF text). I need to create a class for each type, but there are lot of things in common between those classes(eg forms).

Upvotes: 1

Views: 873

Answers (3)

Andrew Sledge
Andrew Sledge

Reputation: 10361

You will need to create an additional field that will be a descriptor for that type.

There is a good tutorial here explaining how to use inheritance in Django models

Upvotes: 1

S.Lott
S.Lott

Reputation: 392070

Any clue?

Yes. AFAIK it doesn't work the way you're hoping. Django Models aren't trivially Python classes. They're more like metaclasses which create instances of a kind of "hidden" class definition. Yes, the expected model class exists, but it isn't quite what you think it is. For one thing, the class you use was built for you from your class definition. That's why some static features of Python classes don't work as you'd expect in Django models.

You can't really make use of class-level items like this.

You might want to create an actual field with a default value or something similar.

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

Even after the comments being added to the question, I'm still unclear on why this is being done. There do not seem to be any structural or behavioral differences. These all seem like a single class of objects. Subclasses don't seem to define anything new.

Options.

  1. Simply use the class name instead of this "category" item at the class level. Make the class names good enough that you don't need this "category" item.

  2. Use a property

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

Upvotes: 1

Manoj Govindan
Manoj Govindan

Reputation: 74795

Can you try overriding the __init__ method of the class to assign a category to each instance? For e.g.

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

Upvotes: 0

Related Questions