Skip to main content

Views and Routing

The request-response cycle in this codebase is centered around the HttpRequest and HttpResponse classes. Routing maps incoming URLs to specific view logic, which can be implemented as either functions or classes.

The Request-Response Cycle

The core of the web framework is the transformation of an HttpRequest into an HttpResponse.

HttpRequest and QueryDict

The HttpRequest class (found in django/http/request.py) encapsulates all data sent by the client. Key attributes include:

  • GET and POST: Instances of QueryDict containing URL parameters and form data.
  • FILES: A MultiValueDict containing uploaded files.
  • COOKIES: A dictionary of cookies.
  • META: A dictionary containing standard CGI variables like REMOTE_ADDR and HTTP_USER_AGENT.
  • body: The raw HTTP request body as a bytestring.

QueryDict is a specialized dictionary that handles multiple values for the same key (common in HTML forms). By default, QueryDict instances are immutable. To modify them, you must create a copy:

# Example of modifying request data
mutable_get = request.GET.copy()
mutable_get['new_key'] = 'value'

HttpResponse

The HttpResponse class (in django/http/response.py) is the base for all responses. It stores the content, status code, and headers.

from django.http import HttpResponse

def simple_view(request):
response = HttpResponse("Hello world", content_type="text/plain")
response.status_code = 200
response['X-Custom-Header'] = 'Value'
return response

Routing and URL Configuration

Routing is defined in URLconf modules using path() and re_path() from django/urls/conf.py. These functions create URLPattern or URLResolver objects.

Path and Converters

The path() function uses RoutePattern to match URLs. It supports path converters (like <int:year>) which capture parts of the URL and pass them as keyword arguments to the view.

from django.urls import path
from . import views

urlpatterns = [
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
]

Internally, _route_to_regex in django/urls/resolvers.py converts these paths into regular expressions using registered converters (e.g., IntConverter, StringConverter).

Regular Expression Routing

For more complex matching, re_path() uses RegexPattern:

from django.urls import re_path

urlpatterns = [
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
]

Including Other URLconfs

The include() function allows for modular URL configurations by delegating parts of the URL tree to other modules:

from django.urls import include, path

urlpatterns = [
path('community/', include('aggregator.urls')),
path('contact/', include('contact.urls')),
]

Implementing Views

Views are callables that accept an HttpRequest and return an HttpResponse.

Function-Based Views (FBVs)

Simple views are often implemented as functions. Examples from tests/view_tests/views.py demonstrate basic usage:

def index_page(request):
"""A basic function-based view returning HTML."""
return HttpResponse("<html><body>Dummy page</body></html>")

Class-Based Views (CBVs)

The View class in django/views/generic/base.py provides a structured way to handle different HTTP methods.

  • as_view(): The entry point that returns a callable view function.
  • setup(): Initializes self.request, self.args, and self.kwargs.
  • dispatch(): Routes the request to the appropriate method handler (e.g., get(), post()).
from django.views import View
from django.http import HttpResponse

class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("Hello from a Class-Based View")

Generic Views

The codebase provides several built-in generic views for common patterns:

  • TemplateView: Renders a specific template with a context.
  • RedirectView: Redirects to a given URL or named URL pattern.
# Implementation of TemplateView in django/views/generic/base.py
class TemplateView(TemplateResponseMixin, ContextMixin, View):
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)

Specialized Responses

Several subclasses of HttpResponse provide specialized behavior:

JsonResponse

JsonResponse (in django/http/response.py) automatically serializes data to JSON and sets the Content-Type to application/json.

from django.http import JsonResponse

def json_view(request):
return JsonResponse({'foo': 'bar'})

FileResponse and StreamingHttpResponse

For large files or generated content, StreamingHttpResponse avoids loading the entire response into memory. FileResponse is a specialized version optimized for binary files.

# FileResponse automatically sets Content-Length and Content-Type
from django.http import FileResponse

def download_file(request):
img = open('image.png', 'rb')
return FileResponse(img)

Redirects

HttpResponseRedirect (302) and HttpResponsePermanentRedirect (301) are used to send the client to a different URL.

from django.http import HttpResponseRedirect

def my_redirect_view(request):
return HttpResponseRedirect('/new-url/')