1

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

2
  • They're all just files. Why create separate models? Commented Sep 9, 2010 at 13:58
  • @S.Lott, because i have course model(contains some lessons), each course has ManToOne relation with UploadItems. Each UploadItem is rendered diffrently, added differently, edited differently ... But in some cases(eg template), i don't need to know what type an UploadItem is, i just call my template tag {% render_resource upload_item %} and my templatetag does the rest depending on the type of the uploadItem. Commented Sep 9, 2010 at 17:20

3 Answers 3

1

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__
    
Sign up to request clarification or add additional context in comments.

7 Comments

@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.
@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.
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.
-1: "Django Models aren't Python classes." Wrong technically and philosophically.
@Andrew Sledge: Interesting point. Any clarification or specifics?
|
1

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

Comments

0

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'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.