views:

23

answers:

2

Hi, When using Model class like this:

class MyModel(models.Model):
    def __init__(self, *args, **kwargs):
        self.myfield = models.Field()
        super(MyModel, self).__init__(*args, **kwargs)

It doesn't take into consideration myfield(in the admin form, when saving the object... )

But if i declare like that:

class MyModel(models.Model):
    myfield = models.Field()

It works just fine.

Why?

Edit

I think i have a good reason: I have an abstract class UploadItem that defines a field called file like this: self.file = models.FileField(upload_to=upload_to) As you can see, in each child class, i have to call parent init method with appropriate upload_to variable(say 'videos' for Video model). So i cannot do it the normal way.

+2  A: 

Because the Django ORM code does some serious meta-magic during class definition (just browse the django/db code to see how magic). You are doing an end-run around that magic by creating fields on the fly in the __init__() function.

Is there a really good reason for not creating the class in the normal way? If not, then do it the normal way. If you do have a good reason then get ready to get into the really deep end of the pool -- both of Python and Django.

Peter Rowell
+1  A: 

Setting a dynamic path for the upload_to attribute is absolutely not a good reason for wanting to muck around with model field declaration.

This is something that Django handles already - if you set upload_to to a callable, you can return the correct value dependent on the model instance. See the documentation.

Daniel Roseman
@Daniel Roseman This seems to be the wright solution, but i don't know how to make the child callback be called, sice this won't work: file = models.FileField(upload_to=UploadItem.get_directory)
maroxe
Why won't that work? The callback is called when the file is uploaded. If you have a specific issue with this functionality, please open a new question.
Daniel Roseman
OK, i will do that
maroxe