【问题标题】:No new migration for subclass of subclass of a field字段子类的子类没有新的迁移
【发布时间】:2019-06-03 06:18:23
【问题描述】:

我有以下设置(Django 2.0.6,也在 2.2 中),第一次迁移是使用具有 max_length=64 的字段,现在我想将 DummyCharField.max_length 更改为 255:

class BaseDummyCharField(models.CharField):
    def __init__(self, *args, **kwargs):
        if 'max_length' not in kwargs:
            kwargs['max_length'] = 64
        super().__init__(*args, **kwargs)


class DummyCharField(BaseDummyCharField):
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 255
        super().__init__(*args, **kwargs)


class AnotherDummyCharField(BaseDummyCharField):
    ...


class DummyModel(models.Model):
    dummy = DummyCharField()

在运行makemigrations 时,它只会显示“未检测到更改”。

我也尝试使用deconstruct(),如docs 中所述,但它仍然不起作用。

class DummyCharField(BaseDummyCharField):
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 255
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        del kwargs['max_length']
        return name, path, args, kwargs

作为一种解决方法,我做了以下操作:

class DummyCharField(BaseDummyCharField):
    def __init__(self, *args, **kwargs):
        # If wrapped inside an `if`, it works...
        if 'max_length' not in kwargs:
            kwargs['max_length'] = 255
        ...

我在这里遗漏了什么或者在这种情况下到底是我的错吗?

【问题讨论】:

  • 你做的一切都是正确的。也许你的APP 在INSTALLED_APPS 中丢失了。
  • @gachdavit 我的APP 存在于INSTALLED_APPS 中,初始迁移已创建,一切都已创建。如果我采用上述解决方法,也会创建新的迁移。

标签: python django migration


【解决方案1】:

1。简介

您以错误的方式使用了 __init__() 方法。

而 Django 的 makemigrations 命令,它会分析我们所做的更改。在此过程中,它会调用__init__() 方法生成旧参数和新参数。 (这里,旧参数是 max_length=64,新参数是 max_length=256)


2。罪魁祸首?

__init__() 方法中的语句,kwargs['max_length'] = 255。

每次都使用 max_length=255 初始化模型字段 导致 overwrite 在这里。在检测模型更改时,此语句会导致 No Changes,因为您已将 max_length 设置为 "CONSTANT"。


3。解决方案?

只需在 __init__() 方法中放置一个 if.. 条件。

def __init__(self, *args, **kwargs):
    if 'max_length'  not in kwargs:
        kwargs['max_length'] = 255

4。最终代码片段

class DummyCharField(BaseDummyCharField):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('max_length', 123)
        super().__init__(*args, **kwargs)

5。参考资料--[源码]

  1. makemigrations command module
  2. detecting any changes
  3. MigrationAutodetector 类的changes() 方法
  4. MigrationAutodetector 类的_detect_changes() 方法
  5. MigrationAutodetector 类的generate_altered_fields() 方法
  6. MigrationAutodetector 类的deep_deconstruct() 方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-28
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多