My Goal
I have a django project with a form, and I want to display a preview page before the user submits.
The problem
I can display a preview page using a Django FormPreview, but not all form data is displayed properly. Specifically, if I have a field with choices, the string values of these choices aren't displayed.  I'm also having problems applying template filters to date fields.  The end result is that some data on the preview page is visible but other data is blank:

However, if I display the same data for posts that have actually been submitted, then everything displays properly:

My Code
models.py:
class Game(models.Model):
  # Game Choices
  FOOTBALL = 0
  BASKETBALL = 1
  TENNIS = 2
  OTHER = 3
  GAME_CHOICES = (
      (FOOTBALL, 'Football'),
      (BASKETBALL, 'Basketball'),
      (TENNIS, 'Tennis'),
      (OTHER, 'Other')
    )
  game_id = models.AutoField(primary_key=True)
  location = models.CharField(max_length=200, verbose_name="Location")
  game = models.IntegerField(choices=GAME_CHOICES, default=FOOTBALL)
  game_date = models.DateField(verbose_name='Game Date')
forms.py
class GameForm(ModelForm):
  class Meta:
    model = Game
    fields = (
      'location',
      'game',
      'game_date'
    )
I'm pretty sure that the problem is in my views.py: I'm not sure that I'm processing the POST request the right way to feed all data to the preview page.
views.py
def form_upload(request):
  if request.method == 'GET':
    form = GameForm()
  else:
    # A POST request: Handle Form Upload
    form = GameForm(request.POST) # Bind data from request.POST into a GameForm
    # If data is valid, proceeds to create a new game and redirect the user
    if form.is_valid():
      game = form.save()
      return render(request, 'games/success.html', {})
  return render(request, 'games/form_upload.html', {
    'form': form,
  })
preview.py
class GameFormPreview(FormPreview):
  form_template = 'games/form_upload.html'
  preview_template = 'games/preview.html'
  def done(self, request, cleaned_data):
    # Do something with the cleaned_data, then redirect
    # to a "success" page.
    return HttpResponseRedirect('/games/success')
form_upload.html
...
<form method="post">
  {% csrf_token %}
  <ul><li>{{ form.as_p }}</li></ul>
  <button type="submit">Preview your post</button>
</form>
...
preview.html
{% load humanize %}
...
<h1>Preview your submission</h1>
  <div>
    <p>Location: {{ form.data.location }}</p>
    <p>Game Date: {{ form.data.game_date|date:"l, F d, Y" }}</p>
    <p>Game Type: {{ form.data.get_game_display }}</p>
  </div>
  <div>
    <form action="{% url 'form_upload' %}" method="post">
      {% csrf_token %}
      {% for field in form %}
      {{ field.as_hidden }}
      {% endfor %}
      <input type="hidden" name="{{ stage_field }}" value="2" />
      <input type="hidden" name="{{ hash_field }}" value="{{ hash_value }}" />
      <!-- Submit button -->
      <button type="submit">Submit your post</button>
      <!-- Go back button -->
      <button type="submit">
        <a href="{% url 'form_upload' %}" 
          onClick="history.go(-1);return false;" >
          Go back and edit your post
        </a>
      </button>
      </div>
    </form>
  </div>
...
Two issues
Essentially, I'm having these two issues:
- String values for 
choicesare not displayed. If I use the get_FOO_display() method in mypreview.htmltemplate, it returns blank. However, if I use this in a page after the post has been submitted, it displays properly. - The 
humanizedate filter doesn't work. If I apply ahumanizefilter ({{ form.data.game_date|date:"l, F d, Y" }}) inpreview.html, it also displays blank. Again, this works for submitted posts. 
My question essentially is: what's the right way to use the FormPreview here?
                        
form.datadoes not haveget_FOO_displayattributes. When you access{{ form.data.get_game_display }}in the template, it fails silently and doesn't display anything.The
get_FOO_displayare methods of the instance, so try this instead.Wherever possible you should access data from
form.cleaned_data(which is validated and 'cleaned') instead ofform.data, which is the raw data submitted to the form.The filters don't work with
form.data.game_datebecause it's a raw string. They should work withform.cleaned_data.game_date, which has been converted to a python date object.Finally, you haven't implemented anything in your
donemethod, you've just copied the comment from the docs. You could create a new game usingcleaned_dataas follows: