字段的子类的子类无新迁移

时间:2019-06-03 06:18:23

标签: python django migration

我具有以下设置(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时,它只会显示“未检测到更改”。

我也尝试按照docs中的说明使用deconstruct(),但仍然无法正常工作。

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
        ...

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

1 个答案:

答案 0 :(得分:3)

1。简介

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

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


2。罪魁祸首?

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

“模型字段”使用初始化。每次max_length=255 ,在此处导致 覆盖 。在检测到模型更改时,此语句会导致无更改,因为您已将max_length设置为“常量”


3。解决方案?

只需在 if.. 方法中放入 __init__() 条件。

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 类的
  4. changes()方法
  5. MigrationAutodetector 类的
  6. _detect_changes()方法
  7. MigrationAutodetector 类的
  8. generate_altered_fields()方法
  9. MigrationAutodetector 类的
  10. deep_deconstruct()方法