如何伪造迁移而不创建特定的现有中介 table
How to fake migrations for not to create a specific existing intermediary table
我有以下型号
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")
我在两个 table 上都有相同的 M2M,因为我希望在两个管理表单上显示相同的中间 table。他们还必须使用相同的 table(而不是创建两个单独的 table),因为一个管理表单中的一个更改必须反映到另一个。比如,如果我通过 HareketAdmin
添加一个新的 Hareket
到 VucutBolgesi
,那么同样的结果也应该在 VucutBolgesiAdmin
上可见。
为了实现这一点,我首先从 VucutBolgesi
中删除了 hareketler
M2M 字段,因此 Hareketler
模型将创建中间 table。我将其迁移,然后使用 db_table
属性将 hareketler
添加到 VucutBolgesi
,这样它将识别相同的中介 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
时 django 创建的迁移
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 为每个 makemigrations
创建了相同的 migrations.AddField
解决方法很简单。
您必须确定相关迁移是唯一需要伪造的迁移操作。您必须先使用
创建迁移
python manage.py makemigrations antrenman
然后使用 --fake
应用该迁移
python manage.py migrate --fake antrenman
障碍是,其他开发人员应该知道他们必须 fake 相关迁移。如果除了这个之外还有其他迁移,他们应该先制作它们,然后 fake 这个。
可惜没有参数告诉相关迁移是真的还是假的
是否可以使迁移始终被伪造,只需覆盖 apply 和 unapply 方法即可。这样做的后果没有得到充分调查,但到目前为止它对我有用。
在下面的示例中,我们创建了一个重用 django.contrib.auth.User.group
的 M2M table 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()
我有以下型号
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")
我在两个 table 上都有相同的 M2M,因为我希望在两个管理表单上显示相同的中间 table。他们还必须使用相同的 table(而不是创建两个单独的 table),因为一个管理表单中的一个更改必须反映到另一个。比如,如果我通过 HareketAdmin
添加一个新的 Hareket
到 VucutBolgesi
,那么同样的结果也应该在 VucutBolgesiAdmin
上可见。
为了实现这一点,我首先从 VucutBolgesi
中删除了 hareketler
M2M 字段,因此 Hareketler
模型将创建中间 table。我将其迁移,然后使用 db_table
属性将 hareketler
添加到 VucutBolgesi
,这样它将识别相同的中介 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 为每个 makemigrations
migrations.AddField
解决方法很简单。
您必须确定相关迁移是唯一需要伪造的迁移操作。您必须先使用
创建迁移python manage.py makemigrations antrenman
然后使用 --fake
python manage.py migrate --fake antrenman
障碍是,其他开发人员应该知道他们必须 fake 相关迁移。如果除了这个之外还有其他迁移,他们应该先制作它们,然后 fake 这个。
可惜没有参数告诉相关迁移是真的还是假的
是否可以使迁移始终被伪造,只需覆盖 apply 和 unapply 方法即可。这样做的后果没有得到充分调查,但到目前为止它对我有用。
在下面的示例中,我们创建了一个重用 django.contrib.auth.User.group
的 M2M table 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()