Django 1.9 using django sessions in two page forms
<p>How can I use Django sessions to have a user be able to start a form on one page, and move to the next page and have them complete the form? </p>

<p>I have looked into pagination and wizard forms, but I don't get them at all. </p>

<p>When I have one page with a small portion of a model I'm using - in forms - and another page with the rest of the model - <code>forms.py</code> with the rest of the model info - I can use the first form perfectly. </p>

<p>But when I move to the next page, I get an error saying <code>(1048, "Column 'user_id' cannot be null")</code>. </p>

<p>My best guess is to use Django sessions to fix this issue. I don't want the user to have to put in their username and password a second time to get this to work. Any ideas?</p>

<p>my models/forms.py:</p>

<pre><code>class Contact(models.Model):
    user = models.OneToOneField(User)
    subject = models.CharField(max_length=100, blank=True)
    sender = models.EmailField(max_length=100, blank=True)
    message = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.user.username


class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = Contact
        fields = ('username', 'password', 'email')


class ContactForm1(forms.Form):
    class Meta:
        model = Contact
        fields = ('subject', 'sender')


class ContactForm2(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Contact
        fields = ('message',)
</code></pre>

<p>views:</p>

<pre><code>def contact(request):
    registered = False
    if request.method =='POST':
        user = UserForm(request.POST)
        contact = ContactForm1(request.POST)
        if user.is_valid() and contact.is_valid():
            user = user.save()
            user.set_password(user.password)
            user.save()
            contact = contact.save(commit=False)
            contact.user = user
            registered = True
    return render(request, 'mysite/contact.html', {'user': user, 'contact': contact, 'registered': registered})

def contact_second(request):
    if request.method =='POST':
        contact = ContactForm2(request.POST)
        if contact.is_valid():
            contact = contact.save(commit=False)
            contact.save()
    return render(request, 'mysite/contact_two.html', {'contact': contact}
</code></pre>

<p>I think it's a good idea to use sessions to store the forms because you don't want on each page to store the user input into the database because what if s/he change mind in the 3rd page and s/he wants to discard the registration or whatever it is?</p>

<p>I think is better to store the forms in session until you get in the last page, you ensure that everything is valid and then save the data in the database.</p>

<p>So let's say that the bellow code is in one of the view that will serve the first form/page. You retrieve the data from the POST request and you check if the given data are valid using the <code>form.is_valid()</code>, you then store the <code>form.cleaned_data</code> (which contains the user's validated data) to a session variable. </p>

<pre><code>form = CustomForm(request.POST)
...
if form.is_valid():
    request.session['form_data_page_1'] = form.cleaned_data
</code></pre>

<p>Note here that you may need to add code to redirect the user to the next page <code>if form.is_valid()</code> is true, something like this:</p>

<pre><code>if form.is_valid():
    request.session['form_data_page_1'] = form.cleaned_data
    return HttpResponseRedirect(reverse('url-name-of-second-page'))
</code></pre>

<p>Then in any other view let's say in the view that is going to serve the second page you can retreive the from data from the first page like this:</p>

<pre><code>first_page_data = request.session['form_data_page_1']
</code></pre>

<p>And you can do whatever you want with them as if it was after you executed the <code>form.is_valid()</code> in the first view.</p>

python django django-forms django-sessions django-1.9