Django Forms: Collect GET and POST Input

Recommended preparation: set up a Django project and read the Django tutorial overview before trying the code.

Django reads query-string data through request.GET and form submissions through request.POST. Start with a minimal form, then use POST and CSRF protection for any action that changes data.

views.py — read optional GET input

from django.shortcuts import render

def welcome(request):
    name = request.GET.get("name", "Guest")
    return render(request, "welcome.html", {"name": name})

The name value comes from a URL such as /welcome/?name=Alex. A Django template can display it with {{ name }}, which is HTML-escaped by default. You can use the same pattern to display a simple greeting.

On this page — Show page sectionsHide page sections

Create an HTML form with GET

templates/welcome.html

<form action="{% url 'welcome' %}" method="get">
  <label for="name">Your name</label>
  <input id="name" name="name" required>
  <button type="submit">Say hello</button>
</form>
<p>Hello {{ name }}</p>

my_app/urls.py — connect the view

from django.urls import path
from . import views

urlpatterns = [path("welcome/", views.welcome, name="welcome")]

Switch to POST for a submission

GET places form values in the URL. POST submits data in the request body; POST forms must include {% csrf_token %} when Django’s standard CSRF middleware is enabled. POST does not automatically encrypt data: deploy forms over HTTPS.

my_app/views.py — POST-based greeting

from django.shortcuts import render

def welcome(request):
    name = ""
    if request.method == "POST":
        name = request.POST.get("name", "").strip()
    return render(request, "welcome.html", {"name": name})

templates/welcome.html — POST form with CSRF token

<form method="post" action="{% url 'welcome' %}">
  {% csrf_token %}
  <label for="name">Your name</label>
  <input id="name" name="name" required>
  <button type="submit">Submit</button>
</form>
{% if name %}<p>Welcome {{ name }}</p>{% endif %}

Validate empty and oversized values

Basic validation in the view

from django.shortcuts import render

def welcome(request):
    name, error = "", ""
    if request.method == "POST":
        name = request.POST.get("name", "").strip()
        if not name:
            error = "Enter your name."
        elif len(name) > 80:
            error = "Use 80 characters or fewer."
    return render(request, "welcome.html", {"name": name, "error": error})

Server-side validation matters even when the browser input includes required. For more than one or two fields, use a Django Form class instead of copying validation code across views.

Avoid missing-key and accidental HTML problems

PatternResult
request.GET["name"]Raises an exception if the key is missing
request.GET.get("name", "")Returns a default when missing
request.POST.get("name", "")Reads POST data only
{{ name }} in a templateEscapes unsafe HTML by default

Understand the request flow

  • Browser opens a URL mapped to a view.
  • GET or POST values are read from the Django request object.
  • The view validates the data and chooses a template or a redirect.
  • The template renders the response with automatically escaped text.
For larger projects, use a reusable temp_basic.html template and a separate output page. Template inheritance uses {% extends "temp_basic.html" %} and matching {% block content %} tags.

Common errors and troubleshooting

  • 403 CSRF verification failed: include {% csrf_token %} in POST forms and ensure the middleware is enabled.
  • Reverse for welcome not found: make sure the named URL exists.
  • KeyError/MultiValueDictKeyError: use .get() for optional fields.
  • TemplateDoesNotExist: verify the template directory and filename.

Related background: HTML form basics, PHP POST variables and Django’s form handling documentation.

More form-handling examples

Read a checkbox value with get()

views.py — checkbox data may be missing when unchecked

def preferences(request):
    newsletter = request.POST.get("newsletter") == "yes"
    return render(request, "preferences.html", {"newsletter": newsletter})

Collect multiple checkboxes

views.py — QueryDict.getlist()

# HTML: <input type="checkbox" name="topics" value="python"> ...
selected_topics = request.POST.getlist("topics")
# A possible result is ["python", "django"]

Send a successful submission to another page

Fragment inside a POST view — use a named redirect

from django.shortcuts import redirect, render

def welcome_submit(request):
    if request.method == "POST":
        name = request.POST.get("name", "").strip()
        if name:
            request.session["last_name"] = name
            return redirect("welcome")
    return render(request, "welcome.html")

Use messages for feedback after redirect

Fragment: message framework inside a view

from django.contrib import messages
from django.shortcuts import redirect

def submit_success(request):
    messages.success(request, "Your details were saved.")
    return redirect("welcome")

Render existing form values on validation failure

HTML template with retained input and error message

<form method="post">
  {% csrf_token %}
  <input name="name" value="{{ name }}" maxlength="80" required>
  {% if error %}<p role="alert">{{ error }}</p>{% endif %}
  <button type="submit">Save</button>
</form>

Use the request method to choose a template

A minimal two-template workflow

from django.shortcuts import render

def simple_form(request):
    if request.method == "GET":
        return render(request, "simple_form.html")
    return render(request, "simple_result.html", {"value": request.POST.get("value", "")})

Create a reusable base template

templates/temp_basic.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Plus2Net example</title></head>
<body>
  <main>{% block content %}{% endblock %}</main>
</body>
</html>

templates/welcome.html — child template

{% extends "temp_basic.html" %}
{% block content %}
  <h1>Welcome {{ name }}</h1>
{% endblock %}

A base template keeps shared HTML elements in one place. Child templates should override {% block content %} instead of duplicating the entire document structure.

Frequently asked questions

Should a search form use GET or POST?

Use GET for read-only searches you want users to bookmark. Use POST for submissions or changes to server-side data.

Does POST remove the need for validation?

No. All values sent by a browser can be modified, so validate on the server and apply CSRF protection.

How do I show a message on the same page?

Pass the message in a context dictionary to render() and display it inside the template with Django variables.

Previous: Install Django and create a project

Next: Form classes and validation

Browse the complete Django tutorial series.

Additional references

Back to top ↑




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer