Search code examples
pythondjangodjango-south

Django south: access model's __unicode__() method


In django south data migration file, how can I access model's __unicode__() method?

Here is a simple example:

I have a Person class in models.py:

class Person(models.Model):
    name = models.CharField(max_length=255)
    def __unicode__(self):
        return self.name

I then create a data migration with python manage.py datamigration myapp check_person

In the data migration file, I have

class Migration(DataMigration):
    def forwards(self, orm):
        "Write your forwards methods here."
        for person in orm.Person.objects.all():
            print person

Instead of printing the person's name, it prints

Person object
Person object
...

when I do:

from myapp.models import Person

class Migration(DataMigration):
    def forwards(self, orm):
        "Write your forwards methods here."
        print hasattr(orm.Person, '__unicode__')
        print hasattr(Person, '__unicode__')

It prints

False
True

My question is that are those expected? Why can't south orm access __unicode__() method? How can I access it?

Edit: Doing from myapp.models import Person and access Person objects directly by Person.objects.all() does not work for me, because the Person model will be removed from models.py in the next migration.


Solution

  • Instead of using orm.Person.objects.all(), you might want to import the original Person model and query on that instead. orm.Person is not the same thing as Person, it sort of depends on the big data structure models that defined at the end of each migration file to figure out the model information.

    However, orm.Model would still work if your original model has been changed, that's why south could work with models that have changes, the model variable takes a snapshot of the models.py at the time it is created.

    South doc explains this in details.

    South doesn’t freeze every aspect of a model; for example, it doesn’t preserve new managers, or custom model methods, as these would require serialising the python code that runs those method (and the code that depends on, and so forth).

    Edit:

    Sounds like OP would like to use the model __unicode__ property for certain purposes but the model would be deleted right after. Since an import error would occur in this case, I wouldn't bother using __unicode__ anymore, instead I would suggest handling this by manually accessing model fields using orm.Model(since __unicode__ is composed by field values anyway).