Reputation: 1110
Right now, I have an abstract model with several models that inherits its fields. But I have discovered the power of Proxy models, and I want to implement them to my app. This is a picture from now:
class BaseModel(models.Model):
field_1 = models.CharField(max_length=10)
field_2 = models.CharField(max_length=10)
field_3 = models.CharField(max_length=10)
class Meta:
abstract = True
class Model1(BaseModel):
pass
def __unicode__(self):
return self.field_1
class Model2(BaseModel):
pass
def __unicode__(self):
return self.field_1
And this is what I want:
class BaseModel(models.Model):
field_1 = models.CharField(max_length=10)
field_2 = models.CharField(max_length=10)
field_3 = models.CharField(max_length=10)
class Model1(BaseModel):
pass
class Meta:
proxy = True
def __unicode__(self):
return self.field_1
class Model2(BaseModel):
pass
class Meta:
proxy = True
def __unicode__(self):
return self.field_1
The problem is when I remove the "abstract = True" sentence. When I try to migrate, this is the warning:
You are trying to add a non-nullable field 'basemodel_ptr' to Model1 without a default; we can't do that (the database needs something to populate existing rows).
Ok, got it. I read "ptr" is a pointer to the parent model, which is BaseModel, but I don't have any BaseModel, and I cannot get it until I migrate. How can I fix this??
Upvotes: 0
Views: 715
Reputation: 16666
The migrations for this are not trivial.
Currently, your database has two tables:
yourapp_model1
yourapp_model2
Both have the same columns but they use different sequences meaning that their primary keys clash: Both of the tables will start counting their IDs (aka PKs) from 1 onwards. There is a very good chance that there is an instance of Model1
with pk=1
as well as an instance of Model2
with pk=1
and they are not the same.
This is the point of having an abstract model and concrete implementations: share Django code (business logic) while separating the data in the DB. For example, because it is semantically different (different types).
The point of proxy models is the exact opposite: while the data is located in one table in the DB, the proxy models allow you to implement different behaviour but based on the same DB data.
If you are now migrating from abstract models to proxy models it means that what you once considered different types will now become the same types (from a database point of view). As mentioned at the beginning, you will have to move the data from several tables into one and regenerate the IDs for at least part of it. Meaning also, that part of the resources that are currently using these URLs will change/cease to exist/point to a different resource.
Unless you can start from scratch (no live data that you have to support) you should really appreciate the magnitude of this change.
Note that there are other ways to do this. Search for "Django data migration".
Upvotes: 4