text: 
  import os
  
  from django.conf import settings
  from django.core.exceptions import PermissionDenied
  from django.core.files.storage import FileSystemStorage
  from django.forms import Form
  from django.template.response import SimpleTemplateResponse
  from django.urls import NoReverseMatch
  from formtools.wizard.views import SessionWizardView
  
  from cms.models import Page
  from cms.utils import get_current_site
  from cms.utils.i18n import get_site_language_from_request
  
  from .forms import WizardStep1Form, WizardStep2BaseForm, step2_form_factory
  from .wizard_pool import wizard_pool
  
  
  class WizardCreateView(SessionWizardView):
      template_name = 'cms/wizards/start.html'
      file_storage = FileSystemStorage(
          location=os.path.join(settings.MEDIA_ROOT, 'wizard_tmp_files'))
  
      form_list = [
          ('0', WizardStep1Form),
          # Form is used as a placeholder form.
          # the real form will be loaded after step 0
          ('1', Form),
      ]
  
      def dispatch(self, *args, **kwargs):
          user = self.request.user
  
          if not user.is_active or not user.is_staff:
              raise PermissionDenied
          self.site = get_current_site()
          return super().dispatch(*args, **kwargs)
  
      def get_current_step(self):
          """Returns the current step, if possible, else None."""
          try:
              return self.steps.current
          except AttributeError:
              return None
  
      def is_first_step(self, step=None):
          step = step or self.get_current_step()
          return step == '0'
  
      def is_second_step(self, step=None):
          step = step or self.get_current_step()
          return step == '1'
  
      def get_context_data(self, **kwargs):
          context = super().get_context_data(**kwargs)
  
          if self.is_second_step():
              context['wizard_entry'] = self.get_selected_entry()
          return context
  
      def get_form(self, step=None, data=None, files=None):
          if step is None:
              step = self.steps.current
  
          # We need to grab the page from pre-validated data so that the wizard
          # has it to prepare the list of valid entries.
          if data:
              page_key = "{0}-page".format(step)
              self.page_pk = data.get(page_key, None)
          else:
              self.page_pk = None
  
          if self.is_second_step(step):
              self.form_list[step] = self.get_step_2_form(step, data, files)
          return super().get_form(step, data, files)
  
      def get_form_kwargs(self, step=None):
          """This is called by self.get_form()"""
          kwargs = super().get_form_kwargs()
          kwargs['wizard_user'] = self.request.user
          if self.is_second_step(step):
              kwargs['wizard_page'] = self.get_origin_page()
              kwargs['wizard_language'] = self.get_origin_language()
          else:
              page_pk = self.page_pk or self.request.GET.get('page', None)
              if page_pk and page_pk != 'None':
                  kwargs['wizard_page'] = Page.objects.filter(pk=page_pk).first()
              else:
                  kwargs['wizard_page'] = None
              kwargs['wizard_language'] = get_site_language_from_request(
                  self.request,
                  site_id=self.site.pk,
              )
          return kwargs
  
      def get_form_initial(self, step):
          """This is called by self.get_form()"""
          initial = super().get_form_initial(step)
          if self.is_first_step(step):
              initial['page'] = self.request.GET.get('page')
              initial['language'] = self.request.GET.get('language')
          return initial
  
      def get_step_2_form(self, step=None, data=None, files=None):
          entry_form_class = self.get_selected_entry().form
          step_2_base_form = self.get_step_2_base_form()
  
          form = step2_form_factory(
              mixin_cls=step_2_base_form,
              entry_form_class=entry_form_class,
          )
          return form
  
      def get_step_2_base_form(self):
          """
          Returns the base form to be used for step 2.
          This form is sub classed dynamically by the form defined per module.
          """
          return WizardStep2BaseForm
  
      def get_template_names(self):
          if self.is_first_step():
              template_name = self.template_name
          else:
              template_name = self.get_selected_entry().template_name
          return template_name
  
      def done(self, form_list, **kwargs):
          """
          This step only runs if all forms are valid. Simply emits a simple
          template that uses JS to redirect to the newly created object.
          """
          form_one, form_two = list(form_list)
          instance = form_two.save()
          url = self.get_success_url(instance)
          language = form_one.cleaned_data['language']
          if not url:
              page = self.get_origin_page()
              if page:
                  try:
                      url = page.get_absolute_url(language)
                  except NoReverseMatch:
                      url = '/'
              else:
                  url = '/'
  
          return SimpleTemplateResponse("cms/wizards/done.html", {"url": url})
  
      def get_selected_entry(self):
          data = self.get_cleaned_data_for_step('0')
          return wizard_pool.get_entry(data['entry'])
  
      def get_origin_page(self):
          data = self.get_cleaned_data_for_step('0')
          return data.get('page')
  
      def get_origin_language(self):
          data = self.get_cleaned_data_for_step('0')
          return data.get('language')
  
      def get_success_url(self, instance):
          entry = self.get_selected_entry()
          language = self.get_origin_language()
          success_url = entry.get_success_url(
              obj=instance,
              language=language,
          )
          return success_url
  