Нет новой миграции для подкласса подкласса поля - PullRequest
2 голосов
/ 03 июня 2019

У меня есть следующие настройки (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(), как сказано в документах , но он все равно не работал.

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 Ответ

3 голосов
/ 14 июня 2019

1.Intro

Вы неправильно использовали метод __init__().

В то время как команда Django makemigrations анализирует изменения, сделанныенас.Во время процесса он вызывает методы __init__() для генерации старого параметра и новых параметров.(здесь старый параметр max_length=64 и новый параметр max_length=256)


2.Culprit?

Оператор, kwargs['max_length'] = 255 в __init__() метод.

Поле модели инициализируется с max_length=255каждый раз , что вызывало перезапись здесь.При обнаружении изменений модели этот оператор вызывает Без изменений , поскольку для max_length было установлено значение "CONSTANT" .


3.Решение?

Просто поместите условие if.. в метод __init__().

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

4.Финальный фрагмент кода

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

5.Ссылки - [исходный код]

  1. makemigrations командный модуль
  2. обнаружение любых изменений
  3. changes() метод MigrationAutodetector класс
  4. _detect_changes() метод MigrationAutodetector класс
  5. generate_altered_fields() метод MigrationAutodetector класс
  6. deep_deconstruct() метод MigrationAutodetector класс
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...