1

So I added a new "status" field to a django database table. This field needed a default value, so I defaulted it to "New", but I then added a custom migration file that calls the save() method on all of the objects in that table, as I have the save() overridden to check a different table and pull the correct status from that. However, after running this migration, all of the statuses are still set to "New", so it looks like the save isn't getting executed. I tested this by manually calling the save on all the objects after running the migration, and the statuses are updated as expected.

Here's the table model in models.py:

class SOS(models.Model):
    number = models.CharField(max_length=20, unique=True)
    ...
    # the default="New" portion is missing here because I have a migration to remove it after the custom migration (shown below) that saves the models
    status = models.CharField(max_length=20)

    def save(self, *args, **kwargs):
        self.status = self.history_set.get(version=self.latest_version).status if self.history_set.count() != 0 else "New"
        super(SOS, self).save(*args, **kwargs)

And here is the migration:

# Generated by Django 2.0.5 on 2018-05-23 13:50
from django.db import migrations, models

def set_status(apps, schema_editor):
    SOS = apps.get_model('sos', 'SOS')
    for sos in SOS.objects.all():
        sos.save()

class Migration(migrations.Migration):

    dependencies = [
        ('sos', '0033_auto_20180523_0950'),
    ]

    operations = [
        migrations.RunPython(set_status),
    ]

So it seems pretty clear to me that I'm doing something wrong with the migration, but I matched it exactly to what I see in the Django Documentation and I also compared it to this StackOverflow answer, and I can't see what I'm doing wrong. There are no errors when I run the migrations, but the custom one I wrote does run pretty much instanteously, which seems strange, as when I do the save manually, it takes about 5 seconds to save all 300+ entries.

Any suggestions?

P.S. Please let me know if there are any relevant details I neglected to include.

Nealon
  • 2,213
  • 6
  • 26
  • 40

1 Answers1

1

When you run migrations and get Model from apps you can not use custom managers or custom save or create or something like that. This model only have the fields and that's all. If you want to achieve what you want you should add your logic into you migrations like this:

# comment to be more than 6 chars...
def set_status(apps, schema_editor):
    SOS = apps.get_model('sos', 'SOS')
    for sos in SOS.objects.all():
        if sos.history_set.exists():
            sos.status = sos.history_set.get(version=sos.latest_version).status 
        else:
            sos.status =  "New"
        sos.save()
Nealon
  • 2,213
  • 6
  • 26
  • 40
Andrei Berenda
  • 1,946
  • 2
  • 13
  • 27