Every request to a Django site follows the same path: it passes through the middleware, the URLconf picks a view, the view reads data through models, and a template turns that data into a response. This chapter looks at each piece of that path in turn: the MTV pattern, the URLconf, apps, the admin, middleware and settings.
MTV: Model, Template, View
Django splits responsibilities three ways.
What other frameworks call the controller in MVC is shared in Django between the view and the URLconf. Here is a small model to work with:
# polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")
def __str__(self):
return self.question_text
Views and templates
A view is a function (or class) that takes an HttpRequest and returns an HttpResponse. The render() shortcut fills a template with a context, and get_object_or_404() returns a 404 response when the object does not exist.
# polls/views.py
from django.shortcuts import get_object_or_404, render
from .models import Question
def index(request):
latest = Question.objects.order_by("-pub_date")[:5]
return render(request, "polls/index.html", {"latest": latest})
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, "polls/detail.html", {"question": question})
The template language prints values with {{ variable }} and expresses loops, conditions and inheritance with {% tag %}. Output is HTML-escaped automatically, which protects you against XSS.
{% extends "base.html" %}
{% block content %}
<h1>Latest questions</h1>
<ul>
{% for question in latest %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% empty %}
<li>No questions yet.</li>
{% endfor %}
</ul>
{% endblock %}
Class-based views remove a lot of repetition. Generic views such as ListView, DetailView and CreateView give you list, detail and create pages in a few lines.
from django.views import generic
from .models import Question
class DetailView(generic.DetailView):
model = Question
template_name = "polls/detail.html"
The URLconf
A URLconf is a list that maps URL patterns to views. Path converters such as <int:question_id> capture part of the URL and pass it to the view as an argument. Give each pattern a name and you can build URLs with reverse("polls:detail", args=[1]) in Python or the {% url %} tag in templates, so links keep working when the URL layout changes.
# polls/urls.py
from django.urls import path
from . import views
app_name = "polls"
urlpatterns = [
path("", views.index, name="index"),
path("<int:question_id>/", views.detail, name="detail"),
path("q/<int:pk>/", views.DetailView.as_view(), name="question"),
]
app_name sets a URL namespace, so several apps can each have an index route and you can still tell them apart as polls:index.
Apps
An app is a reusable bundle of models, views, templates and URLs. Django only picks up an app's models, templates and management commands once it is listed in INSTALLED_APPS. The AppConfig class in apps.py names the app, and its ready() method is the place for one-time startup work such as connecting signals. django.contrib.auth and django.contrib.admin are themselves apps installed the same way.
The admin
Register a model in admin.py and /admin/ immediately offers list, search and edit pages for it. A ModelAdmin class controls the list columns, filters and search fields.
# polls/admin.py
from django.contrib import admin
from .models import Question
@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
list_display = ["question_text", "pub_date"]
list_filter = ["pub_date"]
search_fields = ["question_text"]
The admin is designed as an internal tool for trusted staff. Pages for your regular users should be built with your own views and templates.
Middleware
Middleware is a layer wrapped around every request and response. Sessions, authentication, CSRF checks and security headers all run as middleware. Requests flow through the MIDDLEWARE list from top to bottom, and responses flow back in reverse order. To write your own, create a callable that receives get_response:
# mysite/middleware.py
import time
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
started = time.monotonic()
response = self.get_response(request)
response["X-Elapsed"] = f"{time.monotonic() - started:.3f}"
return response
Enable it by adding its dotted path, "mysite.middleware.TimingMiddleware", to MIDDLEWARE.
Settings
Read settings anywhere through django.conf.settings. Always write from django.conf import settings rather than importing your settings.py module directly; that way you get the right values when tests change them with override_settings or when DJANGO_SETTINGS_MODULE points to a different module.
Summary
- Models hold your data, templates present it and views handle requests.
- The URLconf maps URLs to views with
path(); names and namespaces let you reverse URLs. - Apps must be listed in
INSTALLED_APPS, and admin.py gives them an admin interface. - Middleware wraps every request and response, and settings are read through
django.conf.settings.
0 commentaire
Se connecter · Connectez-vous pour laisser un commentaire.