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-сценарий с ожидаемым поведением.
- Называет хотя бы один риск: производительность, безопасность, транзакции, память или сопровождение.