我有以下模特
class VucutBolgesi(models.Model):
site = models.ForeignKey(Site)
bolge = models.CharField(verbose_name="Bölge", max_length=75)
hareketler = models.ManyToManyField("Hareket", verbose_name="Hareketler", null=True, blank=True, help_text="Bölgeyi çalıştıran hareketler")
class Hareket(models.Model):
site = models.ForeignKey(Site)
hareket = models.CharField(verbose_name="Hareket", max_length=75 )
bolgeler = models.ManyToManyField(VucutBolgesi, verbose_name="Çalıştırdığı Bölgeler", null=True, blank=True,
help_text="Hareketin çalıştırdığı bölgeler")
我在两个表上都有相同的M2M,因为我希望在两个管理表单上显示相同的中间表。他们还必须使用相同的表(不创建两个单独的表),因为一个管理表单中的一个更改必须反映到另一个。例如,如果我通过Hareket
向VucutBolgesi
添加新的HareketAdmin
,那么VucutBolgesiAdmin
上也会显示相同的结果。
为实现此目的,我首先从hareketler
中移除VucutBolgesi
M2M字段,以便Hareketler
模型创建中间表。我将其迁移,然后将hareketler
添加到具有VucutBolgesi
属性的db_table
,以便它识别相同的中间表。
该领域的最终外观如下:
hareketler = models.ManyToManyField("Hareket", verbose_name="Hareketler", db_table="antrenman_hareket_bolgeler",
null=True, blank=True, help_text="Bölgeyi çalıştıran hareketler")
当我尝试迁移时,django抛出异常
django.db.utils.OperationalError: table "antrenman_hareket_bolgeler" already exists
我应该如何伪造此迁移?
以下是我每次运行makemigrations
dependencies = [
('antrenman', '0005_vucutbolgesi_hareketler'),
]
operations = [
migrations.AddField(
model_name='vucutbolgesi',
name='hareketler',
field=models.ManyToManyField(to='antrenman.Hareket', db_table=b'antrenman_hareket_bolgeler', blank=True, help_text=b'B\xc3\xb6lgeyi \xc3\xa7al\xc4\xb1\xc5\x9ft\xc4\xb1ran hareketler', null=True, verbose_name=b'Hareketler'),
preserve_default=True,
),
]
注意:编辑相关的迁移文件并删除migrations.AddField
不起作用,因为django会为每个migrations.AddField
创建相同的makemigrations
答案 0 :(得分:11)
是否可以使迁移始终被伪造,只需覆盖apply和unapply方法即可。对此的后果没有得到充分的研究,但这对我来说很有用。
在以下示例中,我们创建了一个重用django.contrib.auth.User.group
的M2M表b'profile_user_groups
的迁移:
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('profile', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='organizations',
field=models.ManyToManyField(db_column=b'group_id', db_table=b'profile_user_groups', related_name='members', to='profile.Organization'),
),
]
def apply(self, project_state, schema_editor, collect_sql=False):
return project_state.clone()
def unapply(self, project_state, schema_editor, collect_sql=False):
return project_state.clone()
答案 1 :(得分:3)
解决方案非常简单。
您必须确保相关迁移是唯一需要伪造的迁移操作。您必须先使用
创建迁移python manage.py makemigrations antrenman
然后将该迁移应用于--fake
python manage.py migrate --fake antrenman
让分,其他开发者应该知道他们必须虚假相关的迁移。如果还有其他人与此人一起迁移,他们应该首先进行迁移,然后伪造这个。
太糟糕了,没有参数可以说明相关的迁移应该是真实的还是假的。