如何伪造迁移而不创建特定的现有中间表 [英] How to fake migrations for not to create a specific existing intermediary table

查看:89
本文介绍了如何伪造迁移而不创建特定的现有中间表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型

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,因为我希望在两个管理表单上显示相同的中间表。他们还必须使用同一张表(而不是创建两个单独的表),因为一种管理形式中的一项更改必须反映给另一种形式。就像,如果我通过 HareketAdmin Hareket 添加到 VucutBolgesi >然后在 VucutBolgesiAdmin 上也应显示相同的结果。

I have the same M2M on both table since I wish to display same intermediate table on both admin forms. They also have to use the same table (not create two separate tables) since one change in one admin form must be reflected to the other. Like, If I add a new Hareket to VucutBolgesi through HareketAdmin then the same result shoudl be visible on VucutBolgesiAdmin too.

要实现此目的,我首先删除 hareketler 来自 VucutBolgesi 的M2M字段,因此 Hareketler 模型将创建中间表。我将其迁移,然后将 hareketler 添加到 VucutBolgesi db_table 属性,因此它将识别相同的中间表。

For achieving this, I first remove hareketler M2M field from VucutBolgesi so Hareketler model would create the intermediate table. I migrate this and then add hareketler to VucutBolgesi with db_table attribute so it will recognize the same intermediary table.

该字段的最终外观如下所示

final look of the field is as folows

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抛出异常:

When I try to migrate this, django throw following exception

django.db.utils.OperationalError: table "antrenman_hareket_bolgeler" already exists

我应该如何伪造此迁移?

How should I fake this migration?

下面是每次我运行 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

Note: Editing related migration file and removing migrations.AddField fo not work since django creates the same migrations.AddField with each makemigrations

推荐答案

是否有可能使迁移始终是伪造的,只需覆盖apply和unapply方法即可。其后果尚未得到充分研究,但到目前为止,它对我仍然有效。

Is it possible to make a migration always to be faked, just override the apply and unapply methods. The consequences of this are not sufficiently investigated, but this far it works for me.

在以下示例中,我们创建了一个重新使用 django的迁移。 contrib.auth.User.group 的M2M表 b'profile_user_groups

In the following example we create a migration that reuses django.contrib.auth.User.group's 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()

这篇关于如何伪造迁移而不创建特定的现有中间表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆