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.

