Forums

South Datamigration works and then doesn't?

Here's some code for a south datamigration:

def forwards(self, orm):
    "Write your forwards methods here."
    # Note: Don't use "from appname.models import ModelName".
    # Use orm.ModelName to refer to models in this application,
    # and orm['appname.ModelName'] for models in other applications.

    for p in orm.Widget.objects.all():

        spe = p.subwidget_set.all()[0]
        sp = orm.SubWidget.objects.get(pk=spe.pk) # turned out this didn't help
        print p.foo
        sp.new_foo = p.foo
        sp.new_bar = p.bar
        sp.new_plank = p.plank
        sp.save()
        print sp.new_foo

My models look like this:

class Widget(models.Model):
    objects = WidgetManager()
    # vestigial fields:
    foo = models.IntegerField( default=0 )
    bar = models.IntegerField( default=0 )
    plank =  models.CharField( max_length=3 )

class SubWidget(models.Model):
    widget = models.ForeignKey(Widget, null=True, blank=True, default=None)
    new_foo = models.IntegerField() # tried this with and without 'default=0'
    new_bar = models.IntegerField()
    new_plank =  models.CharField( max_length=3 )

Both print statements return the correct values, but when I then look at the db through the /admin panel, new_foo and new_bar are both 0.

new_plank was a CharField and it takes the value it's supposed to. The other two are IntegerFields and they just keep reverting to 0. Even though they just told me they had the correct values.

I've rerun the bloody thing about fifty times and tried everything I can think of but I just don't understand what's going on.

Any clues?

[edited to show that SubWidget has a Widget ForeignField]

I don't see any link between widgets and subwidgets, and I don't see any confirmation that you're updating the subwidget that you expect to be updating. Drop in a print of the pk of sp or spe and I suspect you'll see that you're just updating the same record over and over.

Thanks for the reply Glenn.

But nope: each SubWidget has one and only one Widget. Ie, SubWidget has a ForeignField 'Widget' which (now I think about it) I probably should have shown. The whole p.subwidget_set.all()[0] thing is just because I don't know of a better way to access subwidgets from the widget side.

With the following prints:

print p.id, sp.id
print p.foo
print sp.new_foo
print

I get this output:

1 1
828
828

2 2
129
129

3 3
2461
2461

4 4
130793
130793

...(etc,etc)

Okay, found the problem. It was a tiny misspelling somewhere high up in the chain. Not South's fault at all. Gragh. Works now.