Search code examples
pythondjangoformsdjango-formsdjango-formwizard

Django form wizard dispatcher


I have a form that is two pages long. Although, the first page asks a basic question, and based on the answer it needs to redirect to one of three forms to be filled out, then submitted. I have created a diagram to help illustrate: enter image description here

I am using django form wizard, but I don't know exactly how to structure my view in order to incorporate this type of logic.

Could someone help me get started with this? Preferably showing some code that needs to be preformed in the django-form SessionWizardView.

Thanks in advance.


Solution

  • You don't need to override get_form if you're solely depending on data from the previous form, you can use a condition_dict, mapping the form by the self defined ID on initializing the WizardView.

    I don't like having too much going on in my urls.py for defining the WizardView, so I wrap the WizardView in a standard view function, and put the normal view function in the urls.py.

        def buy_cart_wizard_view_wrapper(request):
    
            con_dict = {FORM_ID_BILLING_ADDRESS_PICK: db_funcs.check_wizard_has_addresses_buy_cart,
                        FORM_ID_BILLING_ADDRESS: db_funcs.check_wizard_create_billing_pick_buy_cart,
                        FORM_ID_SHIPPING_ADDRESS_PICK: db_funcs.check_wizard_has_addresses_shipping_pick_buy_cart,
                        FORM_ID_SHIPPING_ADDRESS: db_funcs.check_wizard_create_shipping_pick_buy_cart,
                        FORM_ID_SAVED_BUSINESS_PAYMENT_PICK: db_funcs.check_wizard_has_payments_buy_cart,
                        FORM_ID_SAVED_BUSINESS_PAYMENT: db_funcs.check_wizard_create_payment_pick_buy_cart,
            }
    
            form_list = [(FORM_ID_BILLING_ADDRESS_PICK, accounts_forms.AddressPickerForm),
                     (FORM_ID_BILLING_ADDRESS, accounts_forms.BillingAddressForm),
                     (FORM_ID_SHIPPING_ADDRESS_PICK, accounts_forms.AddressPickerForm),
                     (FORM_ID_SHIPPING_ADDRESS, accounts_forms.AddressForm),
                     (FORM_ID_SAVED_BUSINESS_PAYMENT_PICK, accounts_forms.SavedBusinessPmtPickerForm),
                     (FORM_ID_SAVED_BUSINESS_PAYMENT, accounts_forms.SavedBusinessPmtBuyCartForm),
                     ]
    
            return BuyCartWizardView.as_view(form_list,condition_dict=con_dict, initial_dict=ini_dict)(request)
    

    And then an example of a condition check on the previous form, '

    def check_wizard_create_payment_pick_buy_cart(wizard):
        """
        Check if the previous form has an address selected
        """
        cleaned_data = wizard.get_cleaned_data_for_step(FORM_ID_SAVED_BUSINESS_PAYMENT_PICK) or {}
        create_new_payment_ind = cleaned_data.get(FORM_FIELD_NAME) or ''
        if create_new_payment_ind != '':
            return True
        else:
            return False
    

    Returns True to show the form as the next step, False to skip the form and move to the form after that or finish (if out of forms).