Django - 改变迁移中的基础

2024-02-04

由于某些原因,我想对我的模型进行重大更改。我想以某种方式重新设计我的整个设计,但 Django 迁移实现通过不更新我的模型库来记住以前的设计。

让我快速展示一下我以前拥有的和现在拥有的。

app1.TopLevel
  |_ app1.IntermediateLevel
    |_ app2.LowLevel

我有 3 个这样的模型,然后现在我想把这个设计剪掉,变成更适合我当前项目的东西,比如

app2.TopLevel
  |_ app2.LowLevel

我的主要变化是,首先我不再想要中间模型,其次我不需要保留顶部app1.TopLevel那样。

我的数据没有问题(我运行多次迁移,其中一些使用 Python 将数据放入临时字段,然后稍后将数据放回正确的字段并删除这些临时字段)。

我的问题是,当我们创建继承模型时,我们定义了它的基础;

migrations.CreateModel(
        name='IntermediateLevel',
        fields=[
            ('toplevel_ptr', models.OneToOneField(
                 auto_created=True,
                 on_delete=django.db.models.deletion.CASCADE,
                 parent_link=True,
                 primary_key=True, 
                 serialize=False, 
                 to='app1.TopLevel'),
            )
        ],
        bases=('app1.TopLevel',),
    )

在那种情况下我会得到类似的东西

类“LowLevel”中的本地字段“toplevel_ptr”与基类“IntermediateLevel”中名称相似的字段冲突`

我阅读了官方文档和源代码(用于迁移),但到目前为止我还没有看到任何相关内容。是否可以告诉迁移系统我们更改了模型库(其父级)?

否则,我得到的唯一解决方案就是创建新模型,运行 python 迁移将数据从旧模型复制到新模型。然后删除旧模型并重命名新模型以获得我想要的名称。


有同样的问题bases我最终编写了自己的迁移操作,如下所示。不过,值得一提的是,整个过程如下:

  1. 添加新的IntegerField到模型null=True
  2. 复制数据自xxx_ptr到新的领域
  3. 去除xxx_ptrfield
  4. Run the RemoveModelBasesOptions手术
  5. 将临时整数字段重命名为id并将其更改为AutoField
  6. 删除我继承的旧模型

需要注意的一件事是,如果您的模型具有ForeignKey对于您的模型,无论如何它都会保留链接,因此它是安全的。

class RemoveModelBasesOptions(ModelOptionOperation):
    def __init__(self, name):
        super().__init__(name)

    def deconstruct(self):
        kwargs = {
            'name': self.name,
        }
        return (
            self.__class__.__qualname__,
            [],
            kwargs
        )

    def state_forwards(self, app_label, state):
        model_state = state.models[app_label, self.name_lower]
        model_state.bases = (models.Model,)
        state.reload_model(app_label, self.name_lower, delay=True)

    def database_forwards(self, app_label, schema_editor, from_state,
                          to_state):
        pass

    def database_backwards(self, app_label, schema_editor, from_state,
                           to_state):
        pass

    def describe(self):
        return "Remove bases from the model %s" % self.name

    @property
    def migration_name_fragment(self):
        return 'remove_%s_bases' % self.name_lower

然后,只需将其作为迁移中的操作调用即可:

class Migration(migrations.Migration):
    dependencies = [
        ('xxxx', '0025_xxxx'),
    ]

    operations = [
        RemoveModelBasesOptions('Foo')
    ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django - 改变迁移中的基础 的相关文章

随机推荐

  • 将 exp/power 趋势线添加到 ggplot

    我想在我的图中添加指数 幂 趋势 线 我正在使用 ggplot2 包 我有这样的东西 只是有更多的数据 require ggplot2 df lt read table test csv header TRUE sep df meta te
  • 在 docker-entrypoint-initdb.d 中创建 pg_cron 扩展失败

    如果我创建pg cron https github com citusdata pg cron扩展在一个docker entrypoint initdb d init sql文件 docker镜像无法运行并且docker logs
  • 在 Android 应用程序中使用 Stripe 秘密 api 密钥是否安全?

    我在这里看到一些人建议这样做是可以的 这看起来容易得多 但是有人不能反编译您的应用程序并泄露您的密钥吗 提前致谢 您绝对不应该将密钥放入移动应用程序中 正如您所怀疑的 找回您的钥匙会很容易 一旦攻击者获得了您的密钥 他们基本上就可以对您的帐
  • 使用 HttpURLConnection 上传多个图像文件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想使用 HttpURLConnection 上传多个图像文件 并且图像的数量不固定为从 android 上传多少个文件 请不要发送
  • 如何将 fread() 与“https”url 方案一起使用?

    在 fread 的 R 文档中 输入 参数可能是以 http 或 file 开头的 URL 然而在这个 数据表简介 https rawgit com wiki Rdatatable data table vignettes datatabl
  • 分号作为 URL 查询分隔符

    虽然强烈推荐 W3C 源代码 http www w3 org TR 1999 REC html401 19991224 appendix notes html h B 2 2 via 维基百科 http en wikipedia org w
  • Spring Tool Suite 更改键绑定自动完成

    How do I change the keybinding for code autocompletion Ctrl Space is just horrible I would like to have Alt Space But un
  • 项目文件夹已存在且不为空 - netbeans 中出现错误

    我正在使用 NetBeans 7 0 1 当我尝试创建 JAVA 应用程序时 出现错误 项目文件夹已存在且不为空 但事实是项目文件夹不存在 它们的目录中没有同名文件夹 任何建议都会有很大的帮助 提前致谢 当您尝试创建它时 问题是否出现了 或
  • Solrcloud 删除集合错误?

    首先 我创建一个名为的集合用户集合 http xxxxx solr admin collections action CREATE name usercollection numShards 3 replicationFactor 3 ma
  • docker-compose内部DNS服务器127.0.0.11连接被拒绝

    突然 当我使用 docker compose 部署一些新容器时 内部主机名解析不起作用 当我尝试使用 docker compose yaml 文件中的服务名称从另一个容器 ping 一个容器时 我得到了ping bad address my
  • 错误简单示例 lucene 4.0 与源(不是 jar lib)

    编辑 我找到了解决方案 编辑core jar 删除除编解码器包之外的所有包并添加到构建路径 编解码器包必须在jar中 不能是源代码 我无法理解 这是 Lucene 的非常简单的代码 它与 Lucene core lib 一起运行 但是当我使
  • SKLearn KMeans 收敛警告[重复]

    这个问题在这里已经有答案了 我在一维数据集上使用 SKLearn 的 KMeans 聚类 我遇到的错误是 当我运行代码时 我得到一个ConvergenceWarning ConvergenceWarning Number of distin
  • Pinterest Api 限制返回的 pin 数量

    使用此请求获取 Pinterest Api 用户的 pin 来自pinterest API 文档 https stackoverflow com questions 9951045 pinterest api documentation h
  • 泛型,其中 T 是实现接口的类

    我有一个界面 interface IProfile 和一个类 Serializable class Profile IProfile private Profile private to ensure only xmlserializer
  • 查看用户最近执行的Android任务

    我想查看我的 Android 手机最近的任务 我尝试了一些来自互联网的代码 但没有一个能正常工作 我只想获取用户最后执行的应用程序的PID和名称 例如 如果我执行计算器应用程序 然后执行我创建的最近任务应用程序 则该应用程序应该能够告诉我类
  • 本地时间(以毫秒为单位)

    我怎样才能通过图书馆提升获得当前时间 我可以做这个 ptime now boost posix timesecond clock local time tm d tm to tm now 但最后一个时间单位tm结构是第二位 我需要以毫秒为单
  • 用于 Git 更新的 RSS 提要

    是否有我可以订阅的 RSS Atom 提要或 Git 更新邮件列表 我发现很难跟上最新版本 因为我无法知道新版本何时发布 对于 msysgit Windows 端口 它只是 Google Code 提供的 feed http code go
  • 可以停止由 VIsual Studio 2015 生成 *.ipdb *.iobj 文件吗?

    在 Visual Studio Community 2015 中 Visual C 项目在其 Release 文件夹中生成 ipdb 文件和 iobj 文件 现在在 Visual Studio Community 2013 中 我从未见过在
  • C++ 重载运算符 [ ][ ]

    我有 CMatrix 类 其中是指向值数组的 双指针 class CMatrix public int rows cols int arr 我只需要通过键入以下内容来访问矩阵的值 CMatrix x x 0 0 23 我知道如何使用以下方法
  • Django - 改变迁移中的基础

    由于某些原因 我想对我的模型进行重大更改 我想以某种方式重新设计我的整个设计 但 Django 迁移实现通过不更新我的模型库来记住以前的设计 让我快速展示一下我以前拥有的和现在拥有的 app1 TopLevel app1 Intermedi