Django error: got multiple values for keyword argument

前端 未结 3 1536
你的背包
你的背包 2020-12-31 00:51

I get the following error when instantiating a Django form with a the constructor overriden:

__init__() got multiple values for keyword argument \'collection         


        
相关标签:
3条回答
  • 2020-12-31 01:24

    Daniel Roseman's solution is to handle a mixture of *args and **kwargs better, but gruszczy's explanation is the correct one:

    You have defined CreateCollectionForm.__init__ with this signature:

    def __init__(self, collection_type, user=None, parent=None, *args, **kwargs)
    

    And you are then calling it like this:

    form = CreateCollectionForm(
        request.POST, 
        collection_type=collection_type, 
        parent=parent, 
        user=request.user
    )
    

    self is assigned implicitly during the call. After that, Python sees only one positional argument: request.POST, which is assigned as collection_type, the first parameter. Then, the keyword arguments are processed, and when Python sees another keyword argument names collection_type, then it has to throw a TypeError.

    Daniel's solution is a good one, by removing all named parameters, it is much easier to handle things like this, and to pass them up through super() to higher-level constructors. Alternately, you need to make the post dictionary the first formal parameter to your __init__ method, and pass it up to the superclass.

    0 讨论(0)
  • 2020-12-31 01:25

    It's pretty simple: you pass request.POST and only afterward you put argument for collection_type. Onto what request.POST will be put? There is not place for that. Watch this:

    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 aren't.

    0 讨论(0)
  • 2020-12-31 01:41

    You're passing the collection_type argument in as a keyword argument, because you specifically say collection_type=collection_type in your call to the form constructor. So Python includes it within the kwargs dictionary - but because you have also declared it as a positional argument in that function's definition, it attempts to pass it twice, hence the error.

    However, what you're trying to do will never work. You can't have user=None, parent=None before the *args dictionary, as those are already kwargs, and args must always come before kwargs. The way to fix it is to drop the explicit definition of collection_type, user and parent, and extract them from kwargs within the function:

    def __init__(self, *args, **kwargs):
        collection_type = kwargs.pop('collection_type', None)
        user = kwargs.pop('user', None)
        parent = kwargs.pop('parent', None)
    
    0 讨论(0)
提交回复
热议问题