How to call a static methods on a django model class during a south migration
Asked Answered
O

3

30

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 @staticmethods 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 data 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.

Opaque answered 22/7, 2010 at 22:56 Comment(0)
I
47

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.

Inamorata answered 23/7, 2010 at 5:20 Comment(1)
thx, It sounds like a good reason, but some times it's really a lot of pain for not allowed to use it. Maybe there should be some settings that can change be behavior, and the developer is responsible for keep method there in later versions of the code, if he/she turn it on.Iain
P
7

Here's the pertinent section of the South docs explaining why your methods don't work:

Rationale behind the serialisation

Processional answered 27/7, 2010 at 7:12 Comment(1)
Link become broken, here is the latest cached version: web.archive.org/web/20120502060506/https://south.aeracode.org/…Acrostic
T
1

Aren't you using different names lookup_by_name and lookup_name?

Thurmond answered 22/7, 2010 at 23:15 Comment(2)
Thanks for catching the typo in my question. That is not the problem with my real code.Opaque
I submitted a small change request to fix this typo in the original question. I was browsing this question because I had a similar problem and was distracted by the simple answer.Dickey

© 2022 - 2024 — McMap. All rights reserved.