Обновление до Django 4.0.1 с Django 3.2.10 - сообщение об ошибке "получены как позиционные, так и ключевые аргументы для поля"
Я пытаюсь обновить проект Django с версии 3.2.10 до 4.0.1
При выполнении тестов я получаю следующую ошибку:
File "/Users/akira/Projects/work/speedy/cash_flow/jobs/bank_account/process_flinks_transactions_job.py", line 63, in __init__
super(ProcessFlinksTransactionsJob, self).__init__(*args, **kwargs)
File "/Users/akira/.local/share/virtualenvs/speedy-kJQJ8v9W/lib/python3.8/site-packages/django/db/models/base.py", line 446, in __init__
raise TypeError(
TypeError: ProcessFlinksTransactionsJob() got both positional and keyword arguments for field 'name'.
Код, который вызывает ошибку, следующий:
class ProcessFlinksTransactionsJob(Job):
objects = ProcessFlinksTransactionsJobManager()
def __init__(self, *args, **kwargs):
kwargs.update({"name": ProcessFlinksTransactionsJob.__name__})
super(ProcessFlinksTransactionsJob, self).__init__(*args, **kwargs)
Как мне исправить эту ошибку?
Нашел соответствующую тему на DjangoProject, смотрите ее здесь.
В одном из комментариев говорится:
Это намеренное изменение, см. 73b1b225ce1a3318d4478f90cc0db0a260aba3aa. Эта ошибка была добавлена для предотвращения неправильной конфигурации, когда значения для одних и тех же полей передаются в
.args
иkwargs
, как в вашем случае. Я бы рекомендовал перенести эту логику вsave()
.
Мне не остается ничего другого, как согласиться с Мариушем Фелисяком :)
Я наткнулся на это сегодня, и хотя решение Мариуша имеет смысл, иногда вы можете использовать объект без его сохранения.
Это происходит потому, что когда модель загружается из db, она инстанцируется командой new = cls(*values). Если ваш init задает поле с ключевым словом, то изменение, введенное в #22640, вызовет ошибку при создании объекта из db (как это, вероятно, происходит в ваших тестах).
Исправление, которое сработало для меня - это установка полей на init только если нет args.
В вашем случае это будет:
class ProcessFlinksTransactionsJob(Job):
objects = ProcessFlinksTransactionsJobManager()
def __init__(self, *args, **kwargs):
if not args:
kwargs.update({"name": ProcessFlinksTransactionsJob.__name__})
super(ProcessFlinksTransactionsJob, self).__init__(*args, **kwargs)
Таким образом, объекты будут правильно инстанцироваться при загрузке из db и могут быть созданы программно с сохранением текущего поведения.
Надеемся, что это сработает для вас! :)