Copy-from-base model inheritance.

47 views
Skip to first unread message

Joakim Saario

unread,
Mar 1, 2016, 7:48:36 PM3/1/16
to Django developers (Contributions to Django itself)
Hello!

Wouldn't it be great to be able to inherit django models like any other python class? I.e not like the default multi-table inheritance.

"How would this differ from an abstract model" you may ask. Well, it is sort of like an abstract model inheritance, except for the abstract part where the base model isn't registered
and need to have abstract = True

For example


class NormalModel(models.Model):
    foo
= models.CharField(max_length=10)
    bar
= models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
    buzz
= models.CharField(max_length=10)

   
class Meta:
        copy_from_base
= True

Would be equivalent to

class NormalModel(models.Model):
    foo = models.CharField(max_length=10)
    bar
= models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
    foo
= models.CharField(max_length=10)
    bar
= models.CharField(max_length=10)
    buzz
= models.CharField(max_length=10)

My original use case for this was with django-cms, which didn't play well with the multi-table inheritance when I needed to extend a built in plugin of theirs. So I ended up copying the whole model.
which annoyed me that it was the only way to do it.

This also isolates the models from each other in constrast to multi-table inheritance, as the base class is just copied over to the new class, it shares this functionality with abstract models. Think of it as a kind of reverse abstract model. I wrote some code for this and actually reused much of the code used for abstract models. (see attatched patch)
django-copy-from-base.diff

Anssi Kääriäinen

unread,
Mar 2, 2016, 12:18:39 AM3/2/16
to django-d...@googlegroups.com
The recommended way to do what you are after is:

class AbstractBase(models.Model):
f1 = models.IntegerField()

class Meta:
abstract = True

class Base(AbstractBase):
pass

class Derived(AbstractBase):
f2 = models.IntegerField()


If you can't use the above way, then the way forward would be something like:

class Base(models.Model):
f1 = models.IntegerField()

class Derived(make_abstract(Base)):
f2 = models.IntegerField()

It might be possible to create the make_abstract() method outside of
Django. If not, we might be able to improve internals so that
make_abstract() would be easy to write outside of Django.

I don't think we want this inbuilt, as the make_abstract() model
design is inferior to using real abstract model as base for both
models.

- Anssi
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-develop...@googlegroups.com.
> To post to this group, send email to django-d...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/62b0b093-c7e5-4abb-a797-63277b31d27c%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages