DjangoJuniorTechnical

Что такое архитектура MTV (Model-Template-View) в Django и чем она отличается от MVC?

MTV — это переименованный MVC: Model = данные, View = контроллер (обрабатывает запрос), Template = представление (HTML). Django добавляет URLconf для маршрутизации и Middleware для сквозной обработки.

MTV в Django: Model, Template, View

Django использует паттерн MTV — Model, Template, View. По сути это тот же MVC, но с другими названиями и слегка другим распределением ответственностей. Разберём каждый слой.

Слои MTV

  • Model — описывает структуру данных и бизнес-логику. Соответствует M (Model) в MVC. Это классы, унаследованные от django.db.models.Model, которые Django транслирует в SQL-таблицы.
  • Template — HTML-шаблоны с языком шаблонов Django (DTL) или Jinja2. Отвечает за представление данных пользователю. Соответствует V (View) в MVC.
  • View — функция или класс, принимающий HTTP-запрос, обращающийся к моделям и возвращающий HTTP-ответ (обычно с отрендеренным шаблоном). Соответствует C (Controller) в MVC.

Сравнение с MVC

  • MVC Controller → Django View
  • MVC View → Django Template
  • MVC Model → Django Model

Отличие не в архитектуре, а в терминологии. В классическом MVC контроллер принимает запрос и управляет потоком; в Django этим занимается View. Django ещё добавляет слой маршрутизации через URLconf (urls.py), который разруливает запросы до вызова нужного View.

Пример полного цикла запроса

# models.py
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    published_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title
# views.py
from django.shortcuts import render
from .models import Article

def article_list(request):
    # View обращается к Model
    articles = Article.objects.order_by("-published_at")[:10]
    # View передаёт данные в Template
    return render(request, "articles/list.html", {"articles": articles})
# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("articles/", views.article_list, name="article-list"),
]
# articles/list.html (Template)
# {% for article in articles %}
#   <h2>{{ article.title }}</h2>
#   <p>{{ article.published_at }}</p>
# {% endfor %}

Поток запроса в Django

  • Браузер отправляет GET /articles/
  • Django WSGI/ASGI принимает запрос
  • Middleware обрабатывают запрос (аутентификация, сессии и т.д.)
  • URLconf сопоставляет путь и вызывает article_list
  • View запрашивает данные из Model через ORM
  • View рендерит Template с данными
  • Middleware обрабатывают ответ
  • Django возвращает HTTP-ответ браузеру

Class-Based Views

Помимо функциональных вьюх (FBV) Django поддерживает классовые (CBV) через django.views.generic:

from django.views.generic import ListView
from .models import Article

class ArticleListView(ListView):
    model = Article
    template_name = "articles/list.html"
    context_object_name = "articles"
    ordering = ["-published_at"]
    paginate_by = 10

Подводные камни

  • View в Django — это не View в MVC; путаница в терминах вводит в заблуждение разработчиков с опытом в Rails или Spring MVC.
  • Бизнес-логику часто кладут в View вместо Model или отдельного сервисного слоя — это затрудняет тестирование.
  • Django Template Language намеренно ограничен (нет произвольного Python-кода). Это хорошо для безопасности, но требует выносить логику в templatetags или в View.
  • CBV скрывают поток выполнения: метод dispatch() маршрутизирует по HTTP-методу, get_queryset(), get_context_data() переопределяются для кастомизации — без знания MRO легко потеряться.
  • URLconf — отдельная концепция, не входящая ни в M, ни в T, ни в V; её часто забывают при описании архитектуры.
  • Middleware ортогональны MTV и могут изменять запрос/ответ на любом этапе — это мощно, но добавляет неочевидные зависимости.

Common mistakes

  • Описывать mtv vs mvc только как термин и не показывать механизм на минимальном примере.
  • Игнорировать ошибки, пустые данные, конкурентный доступ или границы транзакции.
  • Не связывать поведение с официальным контрактом Django и реальной эксплуатацией.

What the interviewer is testing

  • Объясняет mtv vs mvc через последовательность действий, а не через набор ключевых слов.
  • Приводит короткий кодовый пример или production-сценарий с ожидаемым поведением.
  • Называет хотя бы один риск: производительность, безопасность, транзакции, память или сопровождение.

Sources

Related topics