Django & Flask Topic
Handling Forms with Flask's request Object
Accessing Form Data with request.form
In Flask, when a form is submitted via POST, the data is available in the request.form object, which behaves like a dictionary.
Basic Form Handling Example:
python
from flask import Flask, request, render_template
app = Flask(__name__)
# Display the form (GET request)
@app.route('/register', methods=['GET'])
def show_registration_form():
return render_template('register.html')
# Handle form submission (POST request)
@app.route('/register', methods=['POST'])
def handle_registration():
# Access form data using request.form
username = request.form['username']
email = request.form['email']
password = request.form['password']
# Process the data (in a real app, you'd save to database, etc.)
print(f"Registering user: {username}, Email: {email}")
return f'Registration successful for {username}!'
# Alternatively, handle both GET and POST in one function
@app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
name = request.form['name']
message = request.form['message']
# Process the contact form
return f'Thank you {name} for your message!'
# GET request - show the form
return render_template('contact.html')
Corresponding HTML Template (register.html):
html
<!DOCTYPE html>
<html>
<head>
<title>Registration</title>
</head>
<body>
<h2>Register</h2>
<form method="POST" action="/register">
<input type="text" name="username" placeholder="Username" required>
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Register</button>
</form>
</body>
</html>
Safe Form Data Access
Instead of using request.form['key'] which raises a KeyError if the key doesn't exist, use request.form.get('key') which returns None if the key is missing:
python
@app.route('/search', methods=['GET', 'POST'])
def search():
if request.method == 'POST':
# Safe way to access form data
query = request.form.get('query', '') # Default to empty string
category = request.form.get('category') # Returns None if not found
if query:
return f'Search results for: {query}'
else:
return 'Please enter a search term'
return render_template('search.html')
Handling File Uploads with request.files
For file uploads, you need to:
-
Set
enctype="multipart/form-data"in your form -
Use
request.filesto access uploaded files
python
from flask import request, flash
import os
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# Check if the post request has the file part
if 'file' not in request.files:
return 'No file part in the request'
file = request.files['file']
# If user does not select file, browser submits empty file
if file.filename == '':
return 'No selected file'
if file:
# Save the file
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return f'File {filename} uploaded successfully!'
return '''
<!DOCTYPE html>
<html>
<body>
<h2>Upload File</h2>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
</body>
</html>
'''
Handling Multiple Values (Checkboxes, Multi-select)
For form fields that can have multiple values (like checkboxes), use getlist():
python
@app.route('/preferences', methods=['POST'])
def save_preferences():
# For checkboxes with same name
selected_interests = request.form.getlist('interests')
# For multi-select dropdown
selected_categories = request.form.getlist('categories')
return f'Selected interests: {", ".join(selected_interests)}'
Complete Form Handling Example
python
from flask import Flask, request, render_template, redirect, url_for, flash
app = Flask(__name__)
app.secret_key = 'your-secret-key' # Needed for flashing messages
@app.route('/user/create', methods=['GET', 'POST'])
def create_user():
if request.method == 'POST':
# Get form data safely
username = request.form.get('username', '').strip()
email = request.form.get('email', '').strip()
bio = request.form.get('bio', '')
newsletter = request.form.get('newsletter') == 'on' # Checkbox
avatar = request.files.get('avatar')
# Basic validation
errors = []
if not username:
errors.append('Username is required')
if not email:
errors.append('Email is required')
if errors:
for error in errors:
flash(error, 'error')
return render_template('create_user.html')
# Process successful form submission
user_data = {
'username': username,
'email': email,
'bio': bio,
'newsletter': newsletter
}
# Handle file upload
if avatar and avatar.filename:
filename = f"{username}_{avatar.filename}"
avatar.save(os.path.join('uploads', filename))
user_data['avatar'] = filename
flash('User created successfully!', 'success')
return redirect(url_for('user_created'))
return render_template('create_user.html')
Django Connection: Appreciating Django's Form System
The "Raw Mechanics" vs Django's Abstraction
What you learn in Flask is the raw, manual process of form handling:
-
Manually accessing
request.POSTandrequest.FILES -
Writing validation logic by hand
-
Manually rendering form fields in templates
-
Handling file uploads manually
Django's Form Classes - The Automated Approach
Django abstracts all this manual work into Form and ModelForm classes:
Flask (Manual Approach):
python
# Flask - Everything manual
@app.route('/register', methods=['POST'])
def register():
username = request.form.get('username')
email = request.form.get('email')
password = request.form.get('password')
# Manual validation
errors = []
if not username:
errors.append('Username is required')
if not email or '@' not in email:
errors.append('Valid email is required')
if len(password) < 8:
errors.append('Password must be at least 8 characters')
if errors:
return render_template('register.html', errors=errors)
# Process data...
Django (Automated Approach):
python
# Django - forms.py
from django import forms
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=100)
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput, min_length=8)
# Django - views.py
from django.shortcuts import render, redirect
from .forms import RegistrationForm
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid(): # Automatic validation!
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
# Process data...
return redirect('success')
else:
form = RegistrationForm()
return render(request, 'register.html', {'form': form})
Django's ModelForm - Even More Automation
Django can automatically create forms from your models:
python
# models.py
from django.db import models
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
created_at = models.DateTimeField(auto_now_add=True)
# forms.py
from django.forms import ModelForm
from .models import User
class UserForm(ModelForm):
class Meta:
model = User
fields = ['username', 'email'] # Auto-generates form fields
Key Benefits You'll Appreciate After Learning Flask's Manual Approach:
-
Automatic Validation: Django forms handle validation automatically
-
CSRF Protection: Built-in Cross-Site Request Forgery protection
-
Security: Automatic HTML escaping and security measures
-
Template Rendering: Easy form rendering in templates
-
File Handling: Simplified file upload handling with ModelForms
-
Data Cleaning: Automatic data normalization and cleaning
This foundational knowledge makes you appreciate Django's form system much more. You'll understand what Django is doing for you under the hood, rather than just treating it as magic. When you encounter form issues in Django, you'll be able to debug them effectively because you understand the underlying mechanics learned from Flask.
Comments (0)
No comments yet. Be the first to comment!