A view in Django is a Python callable that takes a web request and returns a web response. The response can be HTML, a redirect, an error, an XML document, or an image. The logic can live anywhere inside your project, but by convention veiws are placed in a views.py file within an app or project directory.
Crafting a Basic View
Here is a function-based view that delivers the current server time as HTML:
from django.http import HttpResponse
import datetime
def server_time_view(request):
current_moment = datetime.datetime.now()
content = f"<html><body>Current server time: {current_moment}.</body></html>"
return HttpResponse(content)
Breakdown:
- We import
HttpResponsefromdjango.httpand the standarddatetimelibrary. server_time_viewis the view function. Every view function receives anHttpRequestinstance as its first argument, conventionally namedrequest.- The function builds an
HttpResponseobject containing the rendered content and returns it. Views are always responsible for returning anHttpResponse.
Django handles the flow: when a page is requested, a new HttpRequest object is created, populated with metadata, and passed to the matching view.
Function-Based vs Class-Based Views
You can implement views as functions (FBV) or as classes (CBV).
FBV Example for creating a class record:
def create_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "create_class.html")
CBV Equivalent:
from django.views import View
class ClassCreateView(View):
def get(self, request):
return render(request, "create_class.html")
def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
Remember to update urls.py for a CBV:
url(r'^create_class/$', views.ClassCreateView.as_view()),
Applying Decorators to Views
Decorators on FBVs
FBVs are plain functions, so standard decorator syntax works:
def timeit(method):
def wrapper(*args, **kwargs):
start = time.time()
result = method(*args, **kwargs)
print(f"Execution time: {time.time() - start:.4f}s")
return result
return wrapper
@timeit
def create_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "create_class.html")
Decorators on CBVs
Since class methods differ from standalone functions, use method_decorator to convert a function decorator:
from django.views import View
from django.utils.decorators import method_decorator
class ClassCreateView(View):
@method_decorator(timeit)
def get(self, request):
return render(request, "create_class.html")
def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
For applying logic across all HTTP methods (GET, POST, etc.), override dispatch:
class ProtectedView(View):
def dispatch(self, request, *args, **kwargs):
print('Pre-processing logic')
response = super().dispatch(request, *args, **kwargs)
print('Post-processing logic')
return response
def get(self, request):
return render(request, 'protected.html')
def post(self, request):
data = request.POST.get('user')
return HttpResponse('Protected POST received')
The Request Object
When a request arrives, Django constructs an HttpRequest object and passes it to the view as request. Key attributes and methods include:
- method: HTTP verb (GET, POST, etc.) in uppercase.
- GET / POST: Dictionary-like objects holding GET/POST parameters (use
request.POST.getlist('key')for multi-value fields like checkboxes). - body: Raw request body as bytes.
- FILES: Contains uploaded file data (only populated for POST with
multipart/form-data, otherwise an empty dict-like object). - META: Python dictionary of HTTP headers (e.g.,
CONTENT_LENGTH,REMOTE_ADDR,HTTP_HOST). - user: Represents the logged-in user (
AnonymousUserif not authenticated). - session: Read/write dictionary for session data.
- get_host(): Returns the host header (e.g.,
127.0.0.1:8000). - get_full_path(): URL path plus query string.
- is_ajax(): Returns
Truefor XMLHttpRequest calls (checksHTTP_X_REQUESTED_WITH).
Handling File Uploads
def handle_upload(request):
if request.method == "POST":
uploaded_file = request.FILES["file"]
file_name = uploaded_file.name
with open(file_name, "wb") as destination:
for chunk in uploaded_file.chunks():
destination.write(chunk)
return HttpResponse("Upload completed.")
The Response Object
Every view constructs and returns an HttpResponse. You can pass a string and configure headers:
from django.http import HttpResponse
response = HttpResponse("Page content here.", content_type="text/plain")
response['X-Custom-Header'] = 'custom-value'
del response['X-Custom-Header']
Key Attributes:
content: The response body.charset: Encoding.status_code: HTTP status code.
JsonResponse
A subclass of HttpResponse for JSON APIs:
from django.http import JsonResponse
def json_handler(request):
payload = {'status': 'active', 'items': [1, 2, 3]}
return JsonResponse(payload) # safe=True by default for dicts
# For non-dict data:
return JsonResponse([10, 20, 30], safe=False)
Shortcut Functions
render()
Wraps template loading and rendering into a single call:
from django.shortcuts import render
def profile_page(request):
context = {'username': 'JohnDoe', 'active': True}
return render(request, 'profile.html', context)
redirect()
Returns an HTTP redirect. Accepts a model instance, a view name, or a string path:
from django.shortcuts import redirect
def go_to_home(request):
return redirect('/home/')
def go_to_detail(request):
obj = MyModel.objects.get(pk=1)
return redirect(obj) # calls obj.get_absolute_url()
def go_to_named_view(request):
return redirect('dashboard-view', user='guest') # reverses URL
To issue a permanent redirect (301) instead of a temporary one (302), set permanent=True:
return redirect('/new-location/', permanent=True)
A 302 redirect does not change the search engine's indexed URL, while a 301 passes the ranking to the destination.