pythondjangodjango-formwizarddjango-formtools

Using value from URL in Form Wizard for Django


I'm trying to use this Form Wizard to design a multipage form in Django. I need to catch a value from the URL, which is a client's ID, and pass it to one of the Forms instance, as the form will be built dynamically with specific values for that client.

I have tried redefining the method get_form_kwargs based on this thread, but this isn't working for me. I have the following code in my views.py:

class NewScanWizard(CookieWizardView):
    def done(self, form_list, **kwargs):
        #some code
    
    def get_form_kwargs(self, step):
        kwargs = super(NewScanWizard, self).get_form_kwargs(step)
        if step == '1': #I just need client_id for step 1
            kwargs['client_id'] = self.kwargs['client_id']

        return kwargs

Then, this is the code in forms.py:

from django import forms
from clients.models import KnownHosts
from bson import ObjectId

class SetNameForm(forms.Form): #Form for step 0
    name = forms.CharField()

class SetScopeForm(forms.Form): #Form for step 1, this is where I need to get client_id
    def __init__(self, *args, **kwargs):
        
        super(SetScopeForm, self).__init__(*args, **kwargs)
        client_id = kwargs['client_id']
        clientHosts = KnownHosts.objects.filter(_id=ObjectId(client_id))

        if clientHosts:
            for h in clientHosts.hosts:
                #some code to build the form

When running this code, step 0 works perfectly. However, when submitting part 0 and getting part 1, I get the following error:

_init_() got an unexpected keyword argument 'client_id'

I've done some debugging and I can see that the value for client_id is binding correctly to kwargs, but I have no clue on how to solve this problem. I think this might not be difficult to fix, but I'm quite new to Python and don't get which the problem is.


Solution

  • You should delete cliend_id from kwargs before calling super(SetScopeForm, self).__init__(*args, **kwargs).

    To delete client_id you can use kwargs.pop('client_id', None):

    class SetScopeForm(forms.Form): #Form for step 1, this is where I need to get client_id
        def __init__(self, *args, **kwargs):
            # POP CLIENT_ID BEFORE calling super SetScopeForm
            client_id = kwargs.pop('client_id', None)
            # call super
            super(SetScopeForm, self).__init__(*args, **kwargs)
            clientHosts = KnownHosts.objects.filter(_id=ObjectId(client_id))
    
            if clientHosts:
                for h in clientHosts.hosts:
                    #some code to build the form