2010/11/4 Łukasz Rekucki <[email protected]>
>
> On 3 November 2010 22:17, Marc Aymerich <[email protected]> wrote:
> > Hi,
> > I have 2 abstract classes with an overrided save function, class BaseA and
> > class BaseB. BaseA trigger the models.Model save function, the other
> > doesn't.
> > class BaseA(models.Model):
> >     class Meta:
> >         abstract = True
> >     def save(self, *args, **kwargs):
> >         super(BaseA, self).save(*args, **kwargs)
> >
> > class BaseB(models.Model):
> >     class Meta:
> >         abstract = True
> >
> >    def save(self, *args, **kwargs):
> >        pass
> > Now I define a class that inherits from both of these classes:
> > class test1(BaseA, BaseB):
> >     integer = models.IntegerField()
> > and when I save a test1 object it is not saved into the database. The reason
> > is that BaseB class doesn't call super save function. But actually I don't
> > see why this fact entails the object isn't saved, because models.Model
> > function is called through BaseA. What is the reason of this behavior?
>
> Model.save is never called. The super() in Python doesn't work like
> you think. It needs to be a little bit smarter to make multiple
> inheritance work, so the anwser is a bit complicated.
>
> Here super() looks at the runtime type of `self`, searches for class
> BaseA in it's Method Resolution Order (MRO) and then takes the next
> class in that order. So in your code
>
> class test1(BaseA, BaseB):
>    integer = models.IntegerField()
>
> `test1` will have a MRO of [test1, BaseA, BaseB, Model, ... some
> irrelevant django stuff ... , object] (you can also check that with
> test1.__mro__). Not going into details, immediate base classes are
> always most important with the one on the left side being most
> important of them. So, the super().save() in BaseA will call the save
> method in BaseB which in turn will do nothing and Model.save() will
> never get called.
>
> For more information on MRO you can see the official documentation[1]
> or just google for "Python MRO".
>
> > What can I do in order to save an object into the db when I inherit from 
> > multiple
> > class and one of them doesn't call the super save function?
>
> Fix the class that doesn't call super(). The class should either call
> super() or not provide the method at all. Otherwise it won't play well
> with inheritance.
>
> You can try changing BaseA.save to call Model.save instead of the
> super call, but then BaseA.save will never call BaseB.save if you ever
> decide to put any code there.
>
> Sorry, if it's not very clear.

hi Łukasz, with your explanation I understand perfectly whats going on
here. Thanks !!
Actually at the first time I thought that I would need to define the
save method without calling the super in some specific cases, but now
I see that I need to always call it. :)
Thanks again!


--
Marc

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to