views:

86

answers:

3

Hi, 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).

+1  A: 

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__
    
S.Lott
@S.Lott, i didn't want to create a field specially for this, but since there is no other way, that's what i am going to do. i'll use a choice field, it's more appropriate in this case.
maroxe
@S.Lott, well, this didn't slove my problem, when redefine category field in the Child class to change default to 'video', i get the error: django.core.exceptions.FieldError: Local field 'category' in class 'Video' clashes with field of similar name from base class 'UploadItem'. I cannot neither give a callable because it won't know which class type the created instance is.
maroxe
Should i use managers?
maroxe
You're not creating a new field, you're assigning a new value to an existing field. It's not clear why these are even subclasses. Please update your question to explain what the structural or behavioral difference is. It appears to be simple an attribute value, which doesn't require a subclass.
S.Lott
@S.Lott, i edited the first post
maroxe
-1: "Django Models aren't Python classes."Wrong technically and philosophically.
Andrew Sledge
@Andrew Sledge: Interesting point. Any clarification or specifics?
S.Lott
The SO commenting system is not the proper venue to elaborate on that: it's intended for brevity, not drawn-out discussions about system architecture.
Andrew Sledge
@Andrew Sledge: Interesting point. Nothing specific, though. No reference or link or hint as to what's wrong technically. The philosophical point is irrelevant -- they're discovering technical features of the model class that don't behave like standard classes.
S.Lott
A: 

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'
Manoj Govindan
+1  A: 

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

Andrew Sledge