Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 860
Leopd Avatar asked Jul 22 '10 22:07

Leopd


People also ask

How do you add a new field to a model with new Django migrations?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.

What is static method in Django?

A @staticmethod is a method that knows nothing about the class or instance it was called on unless explicitly given. It just gets the arguments that were passed, no implicit first argument and It's definition is immutable via inheritance.

What is@ classmethod in Django?

In Python, the @classmethod decorator is used to declare a method in the class as a class method that can be called using ClassName. MethodName() . The class method can also be called using an object of the class. The @classmethod is an alternative of the classmethod() function.

What is@ staticmethod used for?

The @staticmethod is a built-in decorator that defines a static method in the class in Python. A static method doesn't receive any reference argument whether it is called by an instance of a class or by the class itself.


2 Answers

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.

like image 59
Tomasz Wysocki Avatar answered Sep 21 '22 23:09

Tomasz Wysocki


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

Rationale behind the serialisation

like image 33
Jason Avatar answered Sep 22 '22 23:09

Jason