Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Django - Model Inheritance - Does it allow you to override a parent model's attribute?

I'm looking to do this:

class Place(models.Model):    name = models.CharField(max_length=20)    rating = models.DecimalField()  class LongNamedRestaurant(Place):  # Subclassing `Place`.    name = models.CharField(max_length=255)  # Notice, I'm overriding `Place.name` to give it a longer length.    food_type = models.CharField(max_length=25) 

This is the version I would like to use (although I'm open to any suggestion): http://docs.djangoproject.com/en/dev/topics/db/models/#id7

Is this supported in Django? If not, is there a way to achieve similar results?

like image 786
Johnny 5 Avatar asked Feb 26 '10 20:02

Johnny 5


People also ask

What is Model inheritance in Django?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not. When the parent model tables are not created as tables it just acts as a container for common fields and methods.

What is proxy model inheritance in Django?

The main Usage of a proxy model is to override the main functionality of existing Model. It is a type of model inheritance without creating a new table in Database. It always query on original model with overridden methods or managers.

Does Django support multiple inheritance?

Django models support multiple inheritance.


1 Answers

Updated answer: as people noted in comments, the original answer wasn't properly answering the question. Indeed, only the LongNamedRestaurant model was created in database, Place was not.

A solution is to create an abstract model representing a "Place", eg. AbstractPlace, and inherit from it:

class AbstractPlace(models.Model):     name = models.CharField(max_length=20)     rating = models.DecimalField()      class Meta:         abstract = True  class Place(AbstractPlace):     pass  class LongNamedRestaurant(AbstractPlace):     name = models.CharField(max_length=255)     food_type = models.CharField(max_length=25) 

Please also read @Mark answer, he gives a great explanation why you can't change attributes inherited from a non-abstract class.

(Note this is only possible since Django 1.10: before Django 1.10, modifying an attribute inherited from an abstract class wasn't possible.)

Original answer

Since Django 1.10 it's possible! You just have to do what you asked for:

class Place(models.Model):     name = models.CharField(max_length=20)     rating = models.DecimalField()      class Meta:         abstract = True  class LongNamedRestaurant(Place):  # Subclassing `Place`.     name = models.CharField(max_length=255)  # Notice, I'm overriding `Place.name` to give it a longer length.     food_type = models.CharField(max_length=25) 
like image 81
qmarlats Avatar answered Sep 18 '22 21:09

qmarlats