python - No new migration for subclass of subclass of a field
问题描述
I have the following setup (Django 2.0.6, also in 2.2), the first migration is with the field having max_length=64
and now I want to change the DummyCharField.max_length
to 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()
When running makemigrations
, it just says "No changes detected".
I also tried using deconstruct()
as told in the docs, but it still didn't work.
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
As a workaround I made the following:
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
...
Am I missing something here or what exactly is my fault in this case?
解决方案
1. Intro
You were using the __init__()
method in wrong way.
While Django's makemigrations
command, it analyzing the changes made by us. During the process, it calls the __init__()
methods to generate the old-parameter and new parameters. (here, old param is max_length=64
and new param is max_length=256
)
2. Culprit?
The statement, kwargs['max_length'] = 255
in __init__()
method.
The Model Field is initialized with max_length=255
everytime which caused an overwrite here. While detecting the model changes, this statement causes No Changes, since you were set max_length
to a "CONSTANT".
3. Solution?
Simply put a if..
condition in __init__()
method.
def __init__(self, *args, **kwargs):
if 'max_length' not in kwargs:
kwargs['max_length'] = 255
4. Final Code Snippet
class DummyCharField(BaseDummyCharField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('max_length', 123)
super().__init__(*args, **kwargs)
5. References--[source code]
makemigrations
command module- detecting any changes
changes()
method ofMigrationAutodetector
class_detect_changes()
method ofMigrationAutodetector
classgenerate_altered_fields()
method ofMigrationAutodetector
classdeep_deconstruct()
method ofMigrationAutodetector
class
推荐阅读
- vb.net - 将 Richtextbox 保存为 .txt 但格式相同 vb.net2010
- c# - Unity 的柏林噪声
- javascript - 无法加载 Facebook Graph API 个人资料图片 URL
- sdl-2 - SDL2 表面和纹理的像素格式不正确
- python - 从 re.findall 命令中删除空字符串
- react-native - 如何在 react-native/redux 中处理外部数据库更新?
- android - 生命周期感知 Codelab 概念
- express - 在下一个功能之后总是发送错误页面
- jquery - Mapbox - 地图顶部的新 L.markers
- android - 如何从 Firebase 检索列表避免异步