Вы передаете аргумент collection_type
в качестве ключевого аргумента, потому что вы специально говорите collection_type=collection_type
при вызове конструктора формы. Поэтому Python включает его в словарь kwargs
- но так как вы также объявили его позиционным аргументом в определении этой функции, он пытается передать его дважды, отсюда и ошибка.
Однако, то, что вы пытаетесь сделать, никогда не сработает. Вы не можете иметь user=None, parent=None
before the *args
dictionary, так как это уже kwargs, и аргументы всегда должны приходить до kwargs. Способ исправить это - отказаться от явного определения типа collection_type, пользователя и родителя, и извлечь их из kwargs в функции:
def __init__(self, *args, **kwargs):
collection_type = kwargs.pop('collection_type', None)
user = kwargs.pop('user', None)
parent = kwargs.pop('parent', None)
Решение Дэниела Розмана заключается в обработке смеси * args
и ** kwargs
лучше, но объяснение Грушчи является правильным:
Вы определили CreateCollectionForm .__ init __
с помощью эта подпись:
def __init__(self, collection_type, user=None, parent=None, *args, **kwargs)
И затем вы вызываете его так:
form = CreateCollectionForm(
request.POST,
collection_type=collection_type,
parent=parent,
user=request.user
)
self
назначается неявно во время вызова. После этого Python видит только один позиционный аргумент: request.POST, которому присваивается значение collection_type
, первый параметр. Затем обрабатываются аргументы ключевого слова, и когда Python видит другое имя аргумента ключевого слова collection_type
, он должен выдать ошибку TypeError.
Решение Дэниела хорошее, удалив со всеми именованными параметрами гораздо проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу.
form = CreateCollectionForm(
request.POST,
collection_type=collection_type,
parent=parent,
user=request.user
)
self
назначается неявно во время вызова. После этого Python видит только один позиционный аргумент: request.POST, которому присваивается значение collection_type
, первый параметр. Затем обрабатываются аргументы ключевого слова, и когда Python видит другое имя аргумента ключевого слова collection_type
, он должен выдать ошибку TypeError.
Решение Дэниела хорошее, удалив со всеми именованными параметрами гораздо проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу.
form = CreateCollectionForm(
request.POST,
collection_type=collection_type,
parent=parent,
user=request.user
)
self
назначается неявно во время вызова. После этого Python видит только один позиционный аргумент: request.POST, которому присваивается значение collection_type
, первый параметр. Затем обрабатываются аргументы ключевого слова, и когда Python видит другое имя аргумента ключевого слова collection_type
, он должен выдать ошибку TypeError.
Решение Дэниела хорошее, удалив со всеми именованными параметрами гораздо проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу.
collection_type
, первый параметр. Затем обрабатываются аргументы ключевого слова, и когда Python видит другое имена аргументов ключевого слова collection_type
, он должен выдать ошибку TypeError.
Решение Дэниела хорошее, удалив со всеми именованными параметрами гораздо проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу.
collection_type
, первый параметр. Затем обрабатываются аргументы ключевого слова, и когда Python видит другое имя аргумента ключевого слова collection_type
, он должен выдать ошибку TypeError.
Решение Дэниела хорошее, удалив со всеми именованными параметрами гораздо проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу.
super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу. Решение хорошее, удалив все именованные параметры, намного проще обрабатывать подобные вещи и передавать их через super ()
конструкторам более высокого уровня. В качестве альтернативы вам нужно сделать словарь сообщений первым формальным параметром вашего метода __ init __
и передать его суперклассу. Все довольно просто: вы передаете request.POST и только после этого задаете аргумент для collection_type. В какой запрос.POST будет вставлен? Для этого нет места. Смотрите:
In [8]: class A:
...: def __init__(self, a, *args):
...: print a, args
...:
...:
In [9]: A(None, a=None)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/gruszczy/Programy/logbuilder/<ipython console> in <module>()
TypeError: __init__() got multiple values for keyword argument 'a'
Move request.POST somewhere else in the call, but remember, that named arguments come after the ones, that isn't.
.