A form is the primary way to collect data from users: logins, search queries, comments, settings. Understanding HTML forms also matters because Django works with them directly through Form and ModelForm.
Basic form structure
<form action="/subscribe/" method="post">
<!-- form fields -->
<button type="submit">Subscribe</button>
</form>
action— the URL where data is sent. If omitted, data is sent to the current URL.method— HTTP method:get(data in the URL) orpost(data in the request body).
Rule: use method="post" for forms that change data on the server. GET is only for search and filters.
The <input> element
The most versatile form element. The type attribute controls its behaviour:
<!-- Text -->
<input type="text" name="username" placeholder="Enter username" />
<!-- Email — browser checks the format -->
<input type="email" name="email" placeholder="you@example.com" />
<!-- Password — characters are hidden -->
<input type="password" name="password" />
<!-- Number -->
<input type="number" name="age" min="18" max="120" />
<!-- Checkbox -->
<input type="checkbox" name="agree" value="yes" />
<!-- Radio button — one from a group -->
<input type="radio" name="theme" value="dark" />
<input type="radio" name="theme" value="light" />
<!-- Hidden field -->
<input type="hidden" name="csrf_token" value="abc123" />
<!-- Submit button -->
<input type="submit" value="Submit" />
Common <input> types:
| Type | Description |
|---|---|
text |
Single-line text |
email |
Email address (with basic validation) |
password |
Password (characters hidden) |
number |
Number |
url |
URL |
tel |
Phone number |
checkbox |
Checkbox |
radio |
Radio button |
file |
File upload |
hidden |
Hidden field |
submit |
Submit button |
The <label> element
Links a text description to a field. Clicking the label activates the field:
<!-- Explicit association via for / id -->
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
<!-- Implicit association — input inside label -->
<label>
Username:
<input type="text" name="username" />
</label>
Always use <label>. It’s critical for accessibility: screen readers announce the label when the field receives focus.
Multi-line text <textarea>
<label for="content">Comment:</label>
<textarea
id="content"
name="content"
rows="5"
cols="40"
placeholder="Write your comment..."
></textarea>
rows and cols set the initial size. The CSS property resize controls whether the user can resize it manually.
Drop-down list <select>
<label for="category">Category:</label>
<select id="category" name="category">
<option value="">-- Choose --</option>
<option value="python">Python</option>
<option value="devops">DevOps</option>
<option value="frontend" selected>Frontend</option>
</select>
The selected attribute marks the default option. The multiple attribute allows selecting several options at once.
The <button> element
<!-- Submit form (default behaviour) -->
<button type="submit">Publish</button>
<!-- Reset form values -->
<button type="reset">Clear</button>
<!-- Plain button (no submit) -->
<button type="button" onclick="preview()">Preview</button>
<button> is more flexible than <input type="submit">: you can nest HTML inside it — icons, images.
Complete form: Contact page
<form action="/contact/" method="post" novalidate>
<!-- Django CSRF token is inserted by the {% csrf_token %} template tag -->
<div class="form-group">
<label for="name">Name:</label>
<input
type="text"
id="name"
name="name"
required
minlength="2"
placeholder="Your name"
/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input
type="email"
id="email"
name="email"
required
placeholder="you@example.com"
/>
</div>
<div class="form-group">
<label for="subject">Subject:</label>
<select id="subject" name="subject" required>
<option value="">-- Choose a subject --</option>
<option value="feedback">Feedback</option>
<option value="collab">Collaboration</option>
<option value="bug">Found a bug</option>
</select>
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea
id="message"
name="message"
rows="6"
required
placeholder="Your message..."
></textarea>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="newsletter" value="yes" />
Subscribe to the newsletter
</label>
</div>
<button type="submit">Send</button>
</form>
Connecting to Django
In a Django view, the form is handled like this:
# views.py
def contact(request):
if request.method == "POST":
name = request.POST.get("name")
email = request.POST.get("email")
# ... process the data
return render(request, "contact.html")
The preferred approach is to use django.forms.Form — it validates data automatically and generates HTML. More on this in the Django forms section.
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!