Migration doesn't work when fields are added using contribute_to_class
|Reported by:||Matt3o12||Owned by:||nobody|
|Severity:||Release blocker||Keywords:||migration, fake, __fake__, contribute_to_class|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
When you create a custom Field that implements the contribute_to_class and add another Field that way, it won't be possible to use migration.
The code I used:
class MyField(models.CharField): def contribute_to_class(self, cls, name): if not cls._meta.abstract: field = CharField(max_length = 20) cls.add_to_class("%s_mycontribute" % name, field) super(MyField, self).contribute_to_class(cls, name)
What happens if the original model is used (app.models.MyModel):
- contribute_to_class is called and adds additional fields (in my example, MyField).
- contribute_to_class calls it super function and adds the original field (CharField).
Everything works. The model has 2 fields: MyField, and CharField.
When python tries to create a migration (now the model __fake__.MyModel is used).
- contribute_to_class is called. The model already has the contributed CharField (with the name %s_mycontribute) (why does the model already have it?).
- MyField with the exactly name is added again (and no exception is thrown?!).
- The original field (MyField) is added.
The view now has 3 fields: MyField, CharField, and CharField again (both CharFields have the same name).
The next step django does is trying to migrate my model but it fails with the exception: "django.db.utils.OperationalError: duplicate column name: charFile_mycontribute" because the field was created twice.
The original model is somewhere copied and the fields in _meta are not cleaned correctly.