fh_bash
fh_bash

Reputation: 1795

Django form __init__() got multiple values for keyword argument

Hello, I'm trying to use a modified __init__ form method, but I am encountering the following error:

TypeError
__init__() got multiple values for keyword argument 'vUserProfile'

I need to pass UserProfile to my form, to get to dbname field, and I think this is a solution (my form code):

class ClienteForm(ModelForm):
class Meta:
    model = Cliente

def __init__(self, vUserProfile, *args, **kwargs):
    super(ClienteForm, self).__init__(*args, **kwargs)
    self.fields["idcidade"].queryset = Cidade.objects.using(vUserProfile.dbname).all()

Calls to constructor ClienteForm() without POST are successful and show me the correct form. But when the form is submitted and the constructor is called with POST, I get the previously described error.

Upvotes: 29

Views: 37808

Answers (3)

alekwisnia
alekwisnia

Reputation: 2354

I think this is the case with ModelForm, but need to check. For me, the solution was:

def __init__(self, *args, **kwargs):
    self.vUserProfile = kwargs.get('vUserProfile', None)
    del kwargs['vUserProfile']
    super(ClienteForm, self).__init__(*args, **kwargs)
    self.fields["idcidade"].queryset = Cidade.objects.using(self.vUserProfile.dbname).all()

Upvotes: 2

Charles Merriam
Charles Merriam

Reputation: 20520

For the help of those others who Google to here: the error comes from init picking up the argument from both a positional argument and the default argument. Daniel Roseman's is accurate for the question as asked.

This can be either:

  1. You put the argument by position and then by keyword:

    class C():
      def __init__(self, arg): ...
    
    x = C(1, arg=2)   # you passed arg twice!  
    
  2. You forgot to put self as the first argument:

    class C():
       def __init__(arg):  ...
    
    x = C(arg=1)   # but a position argument (for self) is automatically 
                   # added by __new__()!
    

Upvotes: 33

Daniel Roseman
Daniel Roseman

Reputation: 599778

You've changed the signature of the form's __init__ method so that vUserProfile is the first argument. But here:

formPessoa = ClienteForm(request.POST, instance=cliente, vUserProfile=profile)

you pass request.POST as the first argument - except that this will be interpreted as vUserProfile. And then you also try to pass vUserProfile as a keyword arg.

Really, you should avoid changing the method signature, and just get the new data from kwargs:

def __init__(self, *args, **kwargs):
    vUserProfile = kwargs.pop('vUserProfile', None)

Upvotes: 51

Related Questions