I get the following error when instantiating a Django form with a the constructor overriden:
__init__() got multiple values for keyword argument 'collection_type'
The __init__()
function (shown below) is exactly as written this but with # code
replaced with my logic. Asside from that I am essentially overriding the form's (which is a ModelForm) constructor.
def __init__(self, collection_type, user=None, parent=None, *args, **kwargs): # code super(self.__class__, self).__init__(*args, **kwargs)
The call that creates the error is shown here:
form = CreateCollectionForm( request.POST, collection_type=collection_type, parent=parent, user=request.user )
I cannot see any reason why the error is popping up.
EDIT: Here is the full code for the constructor
def __init__(self, collection_type, user=None, parent=None, *args, **kwargs): self.collection_type = collection_type if self.collection_type == 'library': self.user = user elif self.collection_type == 'bookshelf' or self.collection_type == 'series': self.parent = parent else: raise AssertionError, 'collection_type must be "library", "bookshelf" or "series"' super(self.__class__, self).__init__(*args, **kwargs)
EDIT: Stacktrace
Environment: Request Method: POST Request URL: http://localhost:8000/forms/create_bookshelf/hello Django Version: 1.1.1 Python Version: 2.6.1 Installed Applications: ['django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'libraries', 'users', 'books', 'django.contrib.admin', 'googlehooks', 'registration'] Installed Middleware: ('django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware') Traceback: File "/Library/Python/2.6/site-packages/django/core/handlers/base.py" in get_response 92. response = callback(request, *callback_args, **callback_kwargs) File "/Library/Python/2.6/site-packages/django/contrib/auth/decorators.py" in __call__ 78. return self.view_func(request, *args, **kwargs) File "/Users/marcus/Sites/marcuswhybrow.net/autolib/libraries/forms.py" in create_collection 13. form = CreateCollectionForm(request.POST, collection_type=collection_type, user=request.user) Exception Type: TypeError at /forms/create_bookshelf/hello Exception Value: __init__() got multiple values for keyword argument 'collection_type'
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With