I'm writing a data migration in south to fix some denormalized data I screwed up in earlier code. The way to figure out the right value for the incorrect field is to call a static method on the django model class. The code looks like this:
class Account(models.Model):
name = models.CharField()
@staticmethod
def lookup_by_name(name):
# There's actually more to it than this
return Account.objects.get(name=name)
class Record(models.Model):
account_name = models.CharField()
acct = models.ForeignKey('Account')
...
class Migration(DataMigration):
def forwards(self, orm):
# Fixing Records with the wrong FK to Account
for record in orm.Record.objects.all():
record.acct = orm.Account.lookup_by_name(record.account_name)
record.save()
But this fails with
AttributeError: type object 'Account' has no attribute 'lookup_by_name'
I'm guessing south just doesn't support @staticmethod
s on model classes?
Trying to import Account directly fails, unless I also import Record directly and completely ignore the ORM object. Is that a safe option, since it's a dat开发者_高级运维a migration and the schema isn't changing? Or should I just run this fix by hand rather than in the context of a south migration.
You can't use methods from models.py in south migrations. The reason is that in the future models.py will evolve and sooner or later you will delete those methods, then migration will be broken.
You should put all code needed by migration in migration file itself.
Here's the pertinent section of the South docs explaining why your methods don't work:
Rationale behind the serialisation
Aren't you using different names lookup_by_name
and lookup_name
?
精彩评论