Search code examples
djangopython-3.xdjango-formsdjango-formwizard

Return New FormWizard With Data From Current FormWizard


Currently, I have a basic FormWizard using ModelForm derived forms for its steps. When the user is done, it saves to the database. Instead of redirecting them back to an empty FormWizard, I'd like to render a new instance of the FormWizard, starting back on the first step, but pre-populate specific fields with the information they entered in the initial form.

Below is the base functionality:

class CustomWizardView(SessionWizardView):
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'uploads'))

    instance = None

    def get_form_instance(self, step):
        if not self.instance:
            self.instance = Post()
        return self.instance

    def done(self, form_list, **kwargs):
        self.instance.user = self.request.user
        self.instance.save()
        return HttpResponseRedirect('/session-form')

And here is how I did it before I realized how large my form needed to be, and that it required FormWizard:

class PostFormView(TemplateView):
    template_name = 'form/form.html'

    def get(self, request):
        form = TestPostForm()
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = TestPostForm(request.POST, request.FILES)

        building_floor_data = 0
        department_data = ''

        if form.is_valid():
            post = form.save(commit=False)
            post.user = request.user
            building_floor_data = form.cleaned_data['building_floor']
            department_data = form.cleaned_data['department']
            post.save()
            # return redirect('form')

        form = TestPostForm()

        form.fields['building_floor'].initial = building_floor_data
        form.fields['department'].initial = department_data

        return render(request, self.template_name, {'form': form})

I'm very new to Django, so this may be a very obvious leap to make. I'm just not getting it.


Solution

  • Ended up figuring it out. You have to overwrite the SessionWizardView's get_form_initial function. You're looking to build a dictionary, the initial dict, inside should be the key value pairs of field name and desired value. For me, the way to retrieve the value was getting the users last entered value in the database using a filtered query. Example below:

    def get_form_initial(self, step):
        initial = {}
        user = self.request.user.username
        if step == '0':
            main_db_query = Post.objects.filter(user__username__exact=user).last()
            if main_db_query:
                initial = {'site': main_db_query.site,
                           'floor': main_db_query.floor,
                           'room_number': main_db_query.room_number,
                           'department': main_db_query.department}
        return self.initial_dict.get(step, initial)