Flask - Redirect & Errors
Flask – Redirect & Errors
Section titled “Flask – Redirect & Errors”Redirecting Users
Section titled “Redirecting Users”Redirects are a fundamental part of web applications. They are used to send the user’s browser from one URL to another. Common use cases include:
- Redirecting after successful form submission (e.g., from a login form to the user’s dashboard).
- Redirecting after an action (e.g., after deleting an item, redirect back to the list view).
- Directing users from an old URL to a new one.
- Enforcing canonical URLs (e.g., adding or removing a trailing slash).
Flask provides the redirect() function to generate redirect responses.
The redirect() Function
Section titled “The redirect() Function”from flask import redirect, url_for
# Inside a view function:def process_action(): # ... perform some action ... # Redirect to the 'show_results' endpoint return redirect(url_for('show_results'))Parameters:
location: The URL to redirect the user to. It is strongly recommended to generate this URL usingurl_for()rather than hardcoding paths.code=302: The HTTP status code for the redirect. Defaults to302 Found(temporary redirect).Response=None: An optional custom Response class to use.
Common Redirect Status Codes:
301 Moved Permanently: Use when a resource has permanently moved to a new location. Search engines typically update their links.302 Found: Default. Indicates a temporary redirect. Clients should continue using the original URL for future requests.303 See Other: Often used after a POST request to redirect the client to a different URL (usually a success page) using a GET request. Helps prevent accidental resubmission if the user refreshes.307 Temporary Redirect: Similar to 302, but instructs the client to reuse the same HTTP method for the new request (e.g., if the original was POST, the redirect request should also be POST).
Example: Redirecting after Login Attempt
from flask import Flask, redirect, url_for, render_template, request, flash
app = Flask(__name__)# Required for flash messagesapp.secret_key = 'redirect-example-secret'
@app.route('/login-redir')def login_form(): # Renders templates/login_redir.html return render_template('login_redir.html')
@app.route('/process-login-redir', methods=['POST'])def process_login(): # Simulate checking credentials if request.form.get('username') == 'admin': flash('Login successful!', 'success') # Redirect to success page using url_for() return redirect(url_for('success_page')) else: flash('Invalid username.', 'error') # Failed login, redirect back to the login form return redirect(url_for('login_form'))
@app.route('/login-success')def success_page(): return 'Logged in successfully!'
# Assumed template: templates/login_redir.html# <!DOCTYPE html><html><head><title>Login</title></head><body># {% with messages = get_flashed_messages(with_categories=true) %}# {% if messages %}# {% for category, message in messages %}<p class="{{category}}">{{ message }}</p>{% endfor %}# {% endif %}# {% endwith %}# <form method="post" action="{{ url_for('process_login') }}"># Username: <input type="text" name="username"><br># <input type="submit" value="Login"># </form></body></html>
if __name__ == '__main__': app.run(debug=True, port=5008)Handling Errors with abort()
Section titled “Handling Errors with abort()”Sometimes, processing a request cannot continue normally due to an error condition (e.g., resource not found, user not authorized, invalid input). In such cases, you should signal an appropriate HTTP error status. Flask provides the abort() function for this.
The abort() Function
Section titled “The abort() Function”abort() immediately stops the execution of the current view function and raises an HTTPException for the given status code. Flask catches this exception and returns the corresponding error page to the client.
from flask import abort, session
@app.route('/product/<int:product_id>')def get_product(product_id): product = find_product_in_db(product_id) # Assume this function exists if product is None: # Product not found, abort with a 404 error abort(404) return render_template('product_details.html', product=product)
@app.route('/admin/config')def admin_config(): if not session.get('is_admin'): # User is not authorized, abort with a 403 error abort(403) return 'Admin Configuration Page'Common Error Status Codes for abort():
400 Bad Request: Invalid request syntax or parameters.401 Unauthorized: Authentication is required but missing or failed.403 Forbidden: Authenticated user lacks permission to access the resource.404 Not Found: The requested resource could not be found.405 Method Not Allowed: The HTTP method used (e.g., POST) is not supported for this URL.410 Gone: The resource used to exist but is permanently unavailable.500 Internal Server Error: A generic code for unexpected server errors.
You can also pass a description argument to abort():
abort(400, description="Missing 'user_id' parameter in request.")Custom Error Pages with @errorhandler
Section titled “Custom Error Pages with @errorhandler”Instead of showing Flask’s default error pages, you can create custom, user-friendly templates for specific HTTP error codes using the @errorhandler() decorator.
from flask import render_template
@app.errorhandler(404)def handle_not_found_error(error): # Log the error if needed: app.logger.warning(f'Page not found: {request.path}') # The 'error' argument contains information about the exception return render_template('errors/404.html'), 404 # Return template and status code
@app.errorhandler(403)def handle_forbidden_error(error): return render_template('errors/403.html'), 403
@app.errorhandler(500)def handle_internal_error(error): # It's often good practice to rollback database sessions here if applicable # db.session.rollback() app.logger.error(f'Server Error: {error}', exc_info=True) return render_template('errors/500.html'), 500
# --- Assumed Templates ---# templates/errors/404.html: "Sorry, the page you requested was not found."# templates/errors/403.html: "Sorry, you do not have permission to access this page."# templates/errors/500.html: "Sorry, something went wrong on our end. Please try again later."# ------------------------When an error corresponding to a registered handler occurs (either through abort() or an unhandled exception leading to a 500 error), Flask will execute the associated error handler function instead of its default behavior.