Ошибка Django: получил несколько значений для аргумента ключевого слова

21
задан Marcus Whybrow 21 December 2009 в 19:09
поделиться

3 ответа

Вы передаете аргумент 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)
43
ответ дан 16 October 2019 в 23:39
поделиться

Решение Дэниела Розмана заключается в обработке смеси * 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 __ и передать его суперклассу.

7
ответ дан 16 October 2019 в 23:39
поделиться

Все довольно просто: вы передаете 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.

.
9
ответ дан 16 October 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: