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.
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")]
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 %}
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.
| Pattern | Result |
|---|---|
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 template | Escapes unsafe HTML by default |
temp_basic.html template and a separate output page. Template inheritance uses {% extends "temp_basic.html" %} and matching {% block content %} tags.{% csrf_token %} in POST forms and ensure the middleware is enabled..get() for optional fields.Related background: HTML form basics, PHP POST variables and Django’s form handling documentation.
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})
views.py — QueryDict.getlist()
# HTML: <input type="checkbox" name="topics" value="python"> ...
selected_topics = request.POST.getlist("topics")
# A possible result is ["python", "django"]
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")
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")
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>
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", "")})
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.
Use GET for read-only searches you want users to bookmark. Use POST for submissions or changes to server-side data.
No. All values sent by a browser can be modified, so validate on the server and apply CSRF protection.
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.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.