Невозможно переопределить настраиваемое поле __init__ и выполнить миграцию, выдает ошибку - PullRequest
0 голосов
/ 02 апреля 2020

Я пытался создать поле пользовательской модели и использовать его в модели, как показано в документах для BetterCharField, показанного здесь (вам, возможно, придется прокрутить немного вниз): https://docs.djangoproject.com/en/3.0/howto/custom-model-fields/#custom -database-types

Мой код в моем models.py выглядит следующим образом, почти дословно из примера с документами:

 from django.db import models

 # Create your models here.

 class BetterCharField(models.Field):
     def __init__(self, max_length, *args, **kwargs):
         self.max_length = max_length
         super().__init__(*args, **kwargs)

     def db_type(self, connection):
         return "char({})".format(self.max_length)

 class MyModel(models.Model):
     my_field = BetterCharField(25)

Однако при попытке запустить python manage.py makemigrations с этим файлом models.py , Я каждый раз получаю следующую ошибку:

Traceback (most recent call last):
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 413, in from_model
    fields.append((name, field.clone()))
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 512, in clone
    return self.__class__(*args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'max_length'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
    output = self.handle(*args, **options)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py", line 142, in handle
    ProjectState.from_apps(apps),
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 221, in from_apps
    model_state = ModelState.from_model(model)
  File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 418, in from_model
    e,
TypeError: Couldn't reconstruct field my_field on polls.MyModel: __init__() missing 1 required positional argument: 'max_length'

Почему это не удается? Мне еще предстояло создать какие-либо миграции для этого проекта, не говоря уже о поле и модели, приведенных здесь. У меня есть позиционный аргумент 25, заданный BetterCharField, когда я инициализирую его в моем файле models.py. Что мне не хватает? У меня был гораздо более сложный вариант использования, но я построил этот пример в совершенно новом тестовом django проекте / приложении прямо из документации, и он все еще не работает.

1 Ответ

1 голос
/ 02 апреля 2020

Это задокументированное поведение :

Вы не можете изменить количество позиционных аргументов в уже перенесенном настраиваемом поле, не подняв TypeError. Старая миграция вызовет модифицированный метод __init__ со старой подписью. Поэтому, если вам нужен новый аргумент, создайте аргумент с ключевым словом и добавьте в конструктор что-то вроде assert 'argument_name' in kwargs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...