在django字段中添加"直通"表并与南方迁移?

dla*_*tte 14 django django-south

看起来这应该是"容易"或至少在某处记录,我只是无法找到它.

让我们说我有一个模型:

class A(models.Model):
    users = models.ManyToMany('auth.User', blank=True)
Run Code Online (Sandbox Code Playgroud)

现在我想迁移到一个through表来向ManyToMany关系添加字段...

class AUsers(models.Model):
    user = models.ForeignKey('auth.User')
    a = models.ForeignKey('A')
    new_field = models.BooleanField()

class A(models.Model):
    users = models.ManyToMany('auth.User', blank=True, through='AUsers')
Run Code Online (Sandbox Code Playgroud)

然后我做:

% ./manage.py schemamigration app --auto
Run Code Online (Sandbox Code Playgroud)

并不奇怪,它告诉我它将通过表删除原始的自动创建并为其创建一个新的AUsers.目前最好的做法是什么?是否有适当的方式迁移到新through表?我db_table在Meta 使用吗?我是不是through=...马上使用...然后做一个schemamigration --auto,然后a datamigration复制当前表(不知何故,不确定...)然后添加through关系,让它杀死表?

这里的诀窍是什么?这真的很难吗?

Luk*_*ger 14

你应该能够很容易地做到这一点.

首先,确保您创建的手动通过表在数据库中具有与Django最初自动创建的表名相同的表名.

因此,首先,让我们在您更改之前考虑手动通过模型:

class AUsers(models.Model):
    user = models.ForeignKey('auth.User')
    a = models.ForeignKey('A')

    class Meta:
        db_table = 'appname_a_user'
Run Code Online (Sandbox Code Playgroud)

这应该与ManyToManyField你以前的功能(几乎)相同.实际上,您可以进行空迁移并应用它,然后使用--auto进行更改(但不要).

现在,像上面的示例代码中一样添加字段,然后运行./manage.py schemamigration appname manual_through_table --empty.这将为您提供一个名为的空迁移####_manual_through_table.py.

在迁移本身,将有一个forwardsbackwards方法.每个人每个需要一行:

def forwards(self, orm):
    db.add_column('appname_a_user', 'new_field', self.gf('django.db.models.fields.BooleanField')(default=False))

def backwards(self, orm):
    db.delete_column('appname_a_user', 'new_field')
Run Code Online (Sandbox Code Playgroud)

这应该可以让你得到你想要的东西.


Mat*_*kes 5

如果有人在尝试使用现代迁移框架执行相同操作时遇到此问题,请执行以下步骤:

  1. 创建一个与内置直通表完全匹配的新模型类
  2. 使用Meta类设置表名以匹配现有表
  3. 生成一个迁移,它将创建新表并将其设置为字段的through.
  4. 如果不运行该迁移,请对其进行编辑以将其包装在migrations. SeparateDatabaseAndState迁移中,其中自动生成的步骤位于state_operations字段中,数据库操作为空.
  5. 根据需要修改直通表,确保正常生成新的迁移.