Passing variables between views and templates

I’m a new hobbyist-level web programmer, working on my own projects. I’m by no means an expert, so I thought I’d ask the experts for advice.

I need to pass data from a template, which uses radio buttons to set a parameter, to a view. The HTML looks like this:

<form method="POST" action="set_power_level{{value}}">
    {% csrf_token %}
    <input type="radio" name="normal" id="power" value="Normal">
    <label for="power" id="Normal">Normal</label><br>

    <input type="radio" name="heroic" id="power" value="Heroic">
    <label for="power" id="Heroic">Heroic</label><br>

    <input type="radio" name="epic" id="power" value="Epic">
    <label for="power" id="Epic">Epic</label><br>

    <input type="radio" name="superhuman" id="power" value="Superhuman">
    <label for="power" id="Superhuman">Superhuman</label><br>
</form>

... etc ... etc ...

<form method="POST" action="{% url 'choose_genre' %}">
    {% csrf_token %}
    <button>Next</button>
</form>

This is rendered by the following view:

def choose_power_level(request):
    context = {}
    if request.method == "POST":
        request.session['campaign_power_level'] = ""
        template = loader.get_template('htdocs/choose_power_level.html')
        return render(request, 'htdocs/choose_power_level.html', context=context)

In the above code snippets, the page is displayed correctly and I can navigate forward and back through the various pages.

Clicking on the Next button needs to save the user’s choice, then render the next page on which the choice has to be displayed. The choice must also be available in later views.

My research indicates that sessions are the way to go and one example is:

Let’s say you have and argument variable called ‘test’ and the value is 123. The following code will assign that to your session variables list.

request.session[‘test’] = 123

Now you can browse the whole website it is still going to be available. Write the following code in ANY view to capture the value of test:

test = request.session[‘test’]

This is all well and good if the designer knows the value of the ‘test’ variable and can include it in a view. But I am using a radio button for the user to specify the value of ‘test’. I think my questions boil down to:

  • How can this radio button choice be saved in a session variable and accessed later?
  • Are sessions appropriate here or should I be using context instead?

I do understand this question has been asked an answered before (I’ve been all over Stack Overflow) but nothing seems to answer the radio button choice mechanism I’m using.

Kind Regards,
Colin

I’m not clear whether your radio buttons currently do anything. You have this at the start:

<form method="POST" action="set_power_level{{value}}">

That action is odd. Are you using any JavaScript you haven’t mentioned?

If not, I would suggest:

  • You have two forms on the page, but only need one. It should include both the radio buttons and the submit button.
  • The radio buttons should all have the same name (but different values, which they already do).
  • The radio buttons should have different ids - an id must be unique on a page. Also change the label tags’ for attributes to match.
  • Now, when you click the Next button, the form will be submitted to your view. You can then get the value from the radio button and save it in the session.

That’s a general overview - does it make sense?

It’s also worth looking at Django Form classes for rendering and validating forms and their fields, rather than doing it manually.

1 Like

I think you have a conceptual problem here, or you used the wrong word. You don’t pass data from the template to the view. You can send data from the browser to the server, and then execute the view again.

Hi All, and thanks for the suggestions so far. I think @boxed is right: this is a conceptual problem. I’m fairly new to all this and don’t really know what I’m talking about.

Anyway, I’ve followed @philgyford 's suggestions and cleaned up the HTML to look like this:

<form method="POST" action="{% url 'choose_power_level' %}">
    {% csrf_token %}

    <div><input type="radio" name="power" id="power_normal" value="Normal"></div>
    <label for="power_normal" id="Normal">Normal</label><br>

    <div><input type="radio" name="power" id="power_heroic" value="Heroic"></div>
    <label for="power_heroic" id="Heroic">Heroic</label><br>

    <div><input type="radio" name="power" id="power_epic" value="Epic"></div>
    <label for="power_epic" id="Epic">Epic</label><br>

    <div><input type="radio" name="power" id="power_superhuman" value="Superhuman"></div>
    <label for="power_superhuman" id="Superhuman">Superhuman</label><br>

    <br><br>
    <input type="submit" value ="Next">

</form>

Experimenting with the view, I have:

def choose_power_level(request):
    context = {}
    if request.method == "POST":
        campaign_power_level = forms.RadioSelect()
        print("def", campaign_power_level)
        template = loader.get_template('htdocs/choose_power_level.html')
        return render(request, 'htdocs/choose_power_level.html', context=context)

(“def” in the print statement simply indicates that the output has been generated inside the defined choose_power_level python function.)

What I see in the console is this:

[27/Oct/2024 12:35:50] "POST /choose_power_level/ HTTP/1.1" 200 1020
def <django.forms.widgets.RadioSelect object at 0x7f3041023a10>

Is there any way of rendering this string of hex into the actual value of the radio button?

Thanks,
Colin

Have you done the official Django tutorial? It covers some of this kind of stuff quite well, and it might be easier to do all of that, carefully, to get a better idea of how forms etc work. Then we can look at what’s not working for you.

Again, this makes no sense. What “value” would that be?

A “widget” in Django Forms is for rendering a field. You are writing all the html for that yourself, so why are you talking about a widget?