Let the games begin!

First of all, we need to make sure we know who the current player is even though we saved them in the database.

We are going to create current_player in myfirstgame/views.py and return that alongside "players" and "form".

current_player is declared as None at the beginning of the index function. The code at the top of the function should look like this:

def index(request):  
    current_player = None
    players = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")

    if request.method == "POST":
[...]

Next, if the POST is valid, we will assign current_player the player's name submitted via the form.
We also need to return current_player with "form" and "players".

The whole code should look like the following:

def index(request):  
    current_player = None
    players = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")

    if request.method == "POST":
        form = PlayerForm(request.POST)
        if form.is_valid():
            player = form.save()
            player.save()
            current_player = player.name
    else:
        form = PlayerForm()

    return render(request, 'myfirstgame/index.html', {'form':form, 'players':players, 'current_player':current_player})

As you can see, everything in between { and } is getting a bit too crowded, we can tidy this up a bit more.

Let's declare context as {} near the top of the function. The context is a dictionary mapping template variable names to Python objects.

context = {}

We can now append "form", "player" and "current_player" to context dictionary.

Replace {'form':form, 'players':players, 'current_player':current_player} with context in return render(...), the code should now look like this:

from django.shortcuts import render
from django.utils import timezone

from .forms import PlayerForm
from .models import Player

def index(request):  
    current_player = None
    context = {}

    context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")

    if request.method == "POST":
        form = PlayerForm(request.POST)
        if form.is_valid():
            player = form.save()
            player.save()
            context['current_player'] = player.name
            return render(request, 'myfirstgame/adventure.html', context)
    else:
        form = PlayerForm()
    context['form'] = form

    return render(request, 'myfirstgame/index.html', context)

It's a lot tidier now. On to the next part.


In this section, after a player submits their name, they will be re-directed to a page with a story starting the game along with two options for them to choose from.

  • Lead-in story - Room with two doors, one is red, the other is blue.
  • Text input box for player to enter their answer: red or blue
  • Submit button

Let's create a new HTML file, myfirstgame/templates/myfirstgame/adventure.html , and add the following:

{% extends 'myfirstgame/base.html' %}

{% block content %}
<div class="content container">
    <div class="row">
        <div class="col-md-12">
            <h2>Welcome, {{ current_player }}!</h2>
            <h3>And so it begins...</h3>

            <p>You enter a room, and you see a red door to your left and a blue door to your right.</p>
            <p>Do you pick the red door or blue door?</p>

            <form action="{% url 'lets_adventure' %}" method="POST">{% csrf_token %}
                <label for="answer">What do you want to do? </label>
                <input id="answer" type="text" name="answer" value="{{ current_answer }}">
                <button type="submit" class="save btn btn-primary">Submit</button>
                <input id="room" type="hidden" name="room" value="two_doors">
                <input id="current_player" type="hidden" name="current_player" value="{{ current_player}}">
            </form>

        </div>
    </div>

    <hr/>

    <div class="row">
        <div class="col-md-12">
            <h3 id="player-listings">List of players in order of latest who played</h3>
            <ul class="player-list">
            {% for player in players %}
                <li><span class="player">{{ player.name }}</span> - Game Over on <em>{{ player.game_end }}</em></li>
            {% endfor %}
            </ul>
        </div>
    </div>
</div>
{% endblock %}

Now open myfirstgame/urls.py, and add the following:

url(r'^adventure/$', views.lets_adventure, name='lets_adventure'),

This will make sure that whenever we visit http://127.0.0.1:8000/adventure, the lets_adventure in myfirstgame/views.py is called.

It should look like this in the final code:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^adventure/$', views.lets_adventure, name='lets_adventure'),
]

Now open myfirstgame/views.py, and add the following:

def lets_adventure(request):
    context = {}
    return render(request, 'myfirstgame/index.html', context)

For now, when we visit http://127.0.0.1:8000/adventure, it will render the page index page as we haven't done anything. This will be default if anything goes wrong, it will just end up on the starting page which is index.html.

Save the file, your Django server should be still running in your terminal, if not, python manage.py runserver to run it again, and go to http://127.0.0.1:8000.

Enter your name, hit submit button. The next screen you see is the following:

Enter "red" in the textbox when asked which door to choose and hit the submit button. This is what you shall see:

Notice a few things missing?

  • List of players from before
  • Textbox just before the submit button.

We haven't done anything with the what was submitted: "red"

Remember in lets_adventure() function we only returned the request to render with an empty context.

Let's start by display the list of players who played before again.

You will need to add the following line:

context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]

This will get the first 5 players (ascending order), and we are going to return it in the context, so this data gets passed back when rendering the HTML page.

In myfirstgame/views.py, it should look like the following:

def lets_adventure(request):
    context = {}

    # New
    context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]

    return render(request, 'myfirstgame/index.html', context)

Save the file, and your Django server should be still running in your terminal. If not, python manage.py runserver to run it again, and go to http://127.0.0.1:8000.

  1. Submit your name
  2. Submit "red"

You should see the following:

Which is a little better. Still got a bit more work to do. Let's start doing something with the data submitted.

Let's add AdventureForm in forms.py:

class AdventureForm(forms.Form): #Note that it is not inheriting from forms.ModelForm
    answer = forms.CharField(max_length=20)
    room = forms.CharField(max_length=20)
    current_player = forms.CharField(max_length=200)

forms.py should now look like the following:

from django import forms

from .models import Player

class PlayerForm(forms.ModelForm):

    class Meta:
        model = Player
        fields = ('name',)

class AdventureForm(forms.Form): #Note that it is not inheriting from forms.ModelForm
    answer = forms.CharField(max_length=20)
    room = forms.CharField(max_length=20)
    current_player = forms.CharField(max_length=200)

We will add the following code in myfirstgame/views.py.

At the top, you will need to import AdventureForm:

from .forms import AdventureForm, PlayerForm
if request.method == "POST":
        form = AdventureForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data

Like before for getting the data from PlayerForm, we need to make sure the data submitted through AdventureForm is valid, if it is, we will get its data.

lets_adventure() function should now look like the following:

from django.shortcuts import render
from django.utils import timezone
from .forms import AdventureForm, PlayerForm
from .models import Player

[...]

def lets_adventure(request):
    context = {}

    context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]

    ## New - start
    if request.method == "POST":
        form = AdventureForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            print(data)
    ## New - end

    return render(request, 'myfirstgame/index.html', context)

Notice print(data)? When you submit a value like "red" when picking a door, this will print out what is contained in data to your output in the terminal. similar to the following:

results matching ""

    No results matching ""