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:
GETandPOST: Instances ofQueryDictcontaining URL parameters and form data.FILES: AMultiValueDictcontaining uploaded files.COOKIES: A dictionary of cookies.META: A dictionary containing standard CGI variables likeREMOTE_ADDRandHTTP_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(): Initializesself.request,self.args, andself.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/')