Ticket #327 (closed defect: fixed)
contribute_to_class can be called multiple times for fields
| Reported by: | carl@… | Owned by: | andrew |
|---|---|---|---|
| Priority: | major | Milestone: | 0.7 |
| Component: | commands | Version: | 0.6-pre |
| Keywords: | Cc: |
Description
I have a custom field that adds another field to the model in its contribute_to_class method. If I try to do a data migration on a model with this field, using the fake ORM, I get "multiple assignments to same column" errors from Postgres. This is because apparently the fake ORM calls contribute_to_class on a field twice, instead of once as Django does. This results in the extra field being added twice.
Haven't had the time yet to wrap my head around the fake ORM code and figure out why this happens and if it's avoidable.
Attachments
Change History
comment:2 Changed 3 years ago by carl@…
Except I'm wrong. What's actually happening is that the auto-added field gets frozen with all the others (which needs to happen, otherwise changes to it won't get autodetected). But when the fake ORM boots up, it gets this auto-added field normally from the frozen fields, and then my custom field adds it again, so it ends up on the fake ORM model twice.
If you can think of a way for South to do this better, that's awesome. But I can't, so feel free to close as wontfix/invalid. I guess it just means that custom fields which add other fields must first check if their auto-added field already exists in order to be compatible with the South FakeORM. Or I might be able to add a flag argument that tells the field not to add its counterpart, and then use introspection rules to tell South to use that argument in its frozen version...
comment:3 Changed 3 years ago by carl@…
The latter approach (preventing creation of the added field when rehydrating frozen models via an arg/attribute and introspection rule) works great; adds a little cruft to the custom field, but that's worth it to get the full benefit of South. You can see the code here: http://bitbucket.org/carljm/django-markitup/src/tip/markitup/fields.py#cl-68
Guess it's up to you if this gotcha is significant enough to warrant a spot in the docs: took up half a day for me :-)

Yes, that sounds just like the kind of bug I'd introduce; most of the core fields don't mind being called more than once. Scheduling for 0.7.