Чтобы изменить первичный ключ на южный, вы можете использовать команду south.db.create_primary_key в datamigration.
Чтобы изменить ваш собственный CharField pk на стандартный AutoField, вам нужно сделать:
1) создайте новое поле в вашей модели
class MyModel(Model):
id = models.AutoField(null=True)
1.1) если у вас есть внешний ключ в какой-либо другой модели этой модели, создайте новое поддельное поле fk для этой модели (используйте IntegerField, затем он будет преобразован)
class MyRelatedModel(Model):
fake_fk = models.IntegerField(null=True)
2) создать автоматическую миграцию на юг и выполнить миграцию:
./manage.py schemamigration --auto
./manage.py migrate
3) создать новую миграцию данных
./manage.py datamigration <your_appname> fill_id
в этой миграции данных заполните эти новые поля id и fk числами (просто перечислите их)
for n, obj in enumerate(orm.MyModel.objects.all()):
obj.id = n
# update objects with foreign keys
obj.myrelatedmodel_set.all().update(fake_fk = n)
obj.save()
db.delete_primary_key('my_app_mymodel')
db.create_primary_key('my_app_mymodel', ['id'])
4) в ваших моделях установите primary_key = True в новом поле pk
id = models.AutoField(primary_key=True)
5) удалить старое поле первичного ключа (если оно не нужно), создать автоматическую миграцию и выполнить миграцию.
5.1) если у вас есть внешние ключи - удалите старые поля внешних ключей (перенести)
6) Последний шаг - восстановление межличностных отношений. Снова создайте реальное поле fk и удалите поле fake_fk, создайте автоматическую миграцию, НО НЕ МИГРАТЬ (!) - необходимо изменить созданную автоматическую миграцию: вместо создания нового fk и удаления fake_fk - переименуйте столбец fake_fk
# in your models
class MyRelatedModel(Model):
# delete fake_fk
# fake_fk = models.InegerField(null=True)
# create real fk
mymodel = models.FoeignKey('MyModel', null=True)
# in migration
def forwards(self, orm):
# left this without change - create fk field
db.add_column('my_app_myrelatedmodel', 'mymodel',
self.gf('django.db.models.fields.related.ForeignKey')(default=1, related_name='lots', to=orm['my_app.MyModel']),keep_default=False)
# remove fk column and rename fake_fk
db.delete_column('my_app_myrelatedmodel', 'mymodel_id')
db.rename_column('my_app_myrelatedmodel', 'fake_fk', 'mymodel_id')
поэтому ранее заполненный fake_fk становится столбцом, который содержит фактические данные отношения, и он не теряется после всех вышеописанных шагов.