urls determination using condition_dict

My intention is to create a wizard and dynamically determine the second form to output by using condition_dict (based on the input selection in the AccountForm) in my urls. The obvious issue is how to uniquely differentiate the account-create urls since determination is not know until the first form is populated.

Any suggestions? Thanks.

urls.py

personal_list = [AccountForm, PersonalForm]
rrif_list = [AccountForm, RrifForm]

urlpatterns = [
    path('account-create/', views.AccountWizardView.as_view(personal_list, condition_dict={'1': show_personal_form}),
         name='account_create'),
    path('account-create/', views.AccountWizardView.as_view(rrif_list, condition_dict={'1': show_rrif_form}),
         name='account_create'),
]

views.py

def show_personal_form(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('0') or {}
    account_type = cleaned_data.get('type')
    result = True if account_type == 'PER' else False
    return result


def show_rrif_form(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('0') or {}
    account_type = cleaned_data.get('type')
    result = True if account_type == 'RRIF' else False
    return result


class AccountWizardView(SessionWizardView):
    template_name = 'pages/plans/accounts/index.html'

    def done(self, form_list, **kwargs):

        account_form = form_list[0]
        if account_form.cleaned_data['type'] == 'PER':
            print("PER")
        elif account_form.cleaned_data['type'] == 'RRIF':
            print("RRIF")
        else:
            print("Accounts")
        return HttpResponse("Worked!!")

This really isn’t the use-case for the django-formtools wizard.
(Quoting directly from the docs at https://django-formtools.readthedocs.io/en/latest/wizard.html:)

The form wizard application splits forms across multiple Web pages.

and

You might want to use this if you have a lengthy form that would be too unwieldy for display on a single page.

If you have a form that needs to dispatch to one of “n” subsequent forms, you’re a lot better off handling the dispatch process yourself. Identify what view needs to be invoked next when you process the post of the first form, and then redirect to it after processing the first form.

Right. This is what I initially planned to do, but upon seeing formtools, I presumed this might have been an option.

Thanks for confirming.

Cheers

I did something similar recently. I ended up having a single URL pattern which caught all possible URLs and sent to it a “dispatcher” function that checked the URL and determined which view to send it to.

Hi Stuart,

Interested. Would you be able to share details on this?

Thanks

This is in my DJ Press package that I’m working on - still very much a work-in-progress, and I certainly wouldn’t use this as a reference of what good looks like, but you can at least see how I did it. Although, I just remembered that I further complicated things by adding a custom converter, which may or may not be necessary for your use case.

A much simpler explanation, is that in your urls.py file, you have a path that uses a regex to capture the URLs that you want, and then you send all these requests to a function that figures out what to do with the request. In my case, I created a dispatcher function and put it in my views.py file. This function tries to work out what the request was looking for, and then it sends the request to the appropriate view.

My use-case is for a blogging/content-management system loosely based on WordPress, which has configurable URL patterns. So it needed some extra logic to try figure out whether a request to “/2024/” is meant to show all blog posts for the year 2024, or perhaps someone has created a page called “2024”. I don’t think I have it all figured out yet (still a work-in-progress!) but it’s working for me at the moment.

I should also mention that before I came up with the idea of a dispatcher function, I had all this logic buit into the urls.py file, but it got very complex and it felt better to have it next to the views themselves.

Hi Stuart, just started looking at your project. I’ll definitely digest to see how you implemented the dispatcher function and see if it would be applicable for my use case.

Thanks again for providing this!!!

Cheers