I have one model in my app running in a server with a few entries. I need to add a SlugField, unique and not-null for this model. The SlugField will be populated based on trading_name. I've changed my model in order to add this new field and modified save method:
class Supplier(StatusModel):
SLUG_MAX_LENGTH = 210
slug = models.SlugField(unique=True, max_length=SLUG_MAX_LENGTH)
trading_name = models.CharField(max_length=200, verbose_name=_('trading name'))
...
def save(self, *args, **kwargs):
self.slug = orig = slugify(self.trading_name)[:Supplier.SLUG_MAX_LENGTH]
for x in itertools.count(1):
if not Supplier.objects.filter(slug=self.slug).exists():
break
# Truncate the original slug dynamically. Minus 1 for the hyphen.
self.slug = "%s-%d" % (orig[:Supplier.SLUG_MAX_LENGTH - len(str(x)) - 1], x)
self.full_clean()
super(Supplier, self).save(*args, **kwargs)
After changing the model, I've run manage.py makemigrations and got this migration as output:
class Migration(migrations.Migration):
dependencies = [
('opti', '0003_auto_20141226_1755'),
]
operations = [
migrations.AddField(
model_name='supplier',
name='slug',
field=models.SlugField(unique=True, default='', max_length=210),
preserve_default=False,
),
]
I can't run manage.py migrate because the default value wont work due to the unique constrant.
My question is: How can I do this with Django 1.7? I need to apply the schema change and keep the current entries in my database.
Unfortunatelly, I found no answer but I could create one solution:
- First I have created a migration that allows the slug field to be nullable;
- Then I have created another migration that populates the slug column with proper values to every row in the model;
- Then another migration which adds the not-null constraint in the column.
You do your model changes (add field, change, etc), then you call manage.py makemigrations, then apply the migrations with manage.py migrate
You can add the field with null=True, then you e.g. make a script to populate it one time
Otherwise, if you need to populate the field within the migration you can write a custom one, see https://docs.djangoproject.com/en/1.7/ref/migration-operations/#writing-your-own
来源:https://stackoverflow.com/questions/27749300/add-non-null-and-unique-field-with-already-populated-model