Django — это высокоуровневый фреймворк Python. Он популярен благодаря своей простоте и эффективности в создании надежных веб-приложений.

В основе архитектуры Django лежит шаблон Model-View-Template (MVT). Хорошее понимание того, как взаимодействуют Модели, Представления и Шаблоны, имеет решающее значение, если вы хотите использовать весь потенциал Django.

Независимо от того, новичок вы в Django или только начинаете, эта статья станет исчерпывающим руководством, показывающим, как эти компоненты работают и взаимодействуют друг с другом для создания динамических веб-приложений.

Чтобы сделать это еще более понятным, мы создадим простое приложение, чтобы помочь вам лучше понять взаимосвязь этих компонентов.

Если вы уже в восторге, давайте перейдем к делу!

Вот что мы рассмотрим:

Предварительные Условия

Для продолжения вам понадобится:

  • Базовое понимание работы веб-приложений, включая клиент-серверную архитектуру.

  • Базовые знания Python.

Что такое архитектура MVT?

Шаблон MVT – это подход Django к организации кодовой базы и рабочего процесса веб-приложения. Компоненты, составляющие эту архитектуру, – это Model, View и Template. Каждый компонент выполняет определенные функции, после чего передает процесс другим компонентам для выполнения своих задач.

Давайте кратко рассмотрим компоненты с конкретными функциями, которые они выполняют:

  • Model: Также известный как слой данных, управляет данными и взаимодействует с базой данных.

  • View: Также известный как слой логики, действует как посредник, обрабатывает логику и управляет потоком данных.

  • Template: Также известный как слой представления, отображает содержимое HTML на пользовательском интерфейсе.

Теперь, когда у вас есть представление о компонентах и их ролях в приложении Django, мы подробно рассмотрим каждый компонент и то, как они взаимодействуют в архитектуре.

Компонент Model

Модели управляют структурой и взаимодействием данных в приложении Django, что делает их основой приложений Django из-за критической роли данных.

Модели Django используют мощную функцию, называемую объектно-реляционным отображением (ORM), которая преодолевает разрыв между реляционной базой данных и кодом Python. Она преобразует объекты Python (классы) в таблицы базы данных, их атрибуты в столбцы, а экземпляры в строки в этих таблицах.

Одним из больших преимуществ ORM является то, что она позволяет взаимодействовать с базой данных, используя объекты Python вместо написания SQL-запросов. Подумайте об этом как о переводчике, который переводит один язык на другой, чтобы аудитория могла понять. В данном случае ORM переводит код Python в SQL-команды, которые может выполнять база данных, и наоборот.

Модели Django инкапсулируют всю логику, связанную с базой данных, и определяют структуру вашей базы данных, действуя как план для данных, которые вы хотите хранить.

Общий формат модели Django

В Django каждая модель следует определенному способу объявления. Вот основная структура объявления модели:

class <model_name>(models.Model):
    <field_name> = models.<field_type>(<optional_field_characteristics>)

Давайте разберем это:

  • class: ключевое слово, используемое для определения модели в Django.

  • model_name: имя модели.

  • models.Model: базовый класс, от которого наследует класс модели.

  • field_name: имя столбца базы данных.

  • field_type: относится к типу данных, которые содержит поле, таким как charField, BooleanField и так далее.

  • optional_field_characteristics: используется для дальнейшего определения поведения поля, такого как max_length, default и так далее.

Пример модели

После того как мы узнали все о моделях до этого момента, мы создадим одну для списка задач. Обычно он содержит заголовок задачи, описание и индикатор о том, были ли задачи выполнены или нет.

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

В этой модели:

  • Task – это имя модели.

  • Модель задачи имеет три поля:

    • title: CharField, который хранит текст, максимальной длиной 100 символов.

    • description: TextField для более длинного текста.

    • completed: BooleanField, который хранит значение True или False, по умолчанию False.

Компонент представления

Представления Django отвечают за обработку запросов пользователей и возврат ответов. Они действуют как мост между Моделью и Шаблоном, собирая данные из объектов Модели, выполняя логические операции над ними (такие как запросы на основе определённых критериев), а затем передавая данные в шаблон для отображения.

Представления могут быть написаны в виде функций или на основе классов, в зависимости от сложности и требований вашего приложения.

Общий формат представления Django

Вот базовая структура представления:

def <view_name>(request):
    # Логика представления здесь...
    return render(request, <template>, <context>)

Давайте разберем это:

  • view_name: имя функции представления.

  • request: HTTP-запрос, отправленный клиентом на сервер Django, может быть вызван отправкой формы или нажатием кнопки.

  • return render: используется для генерации HTML-ответа. Принимает:

    • request: объект запроса, который содержит информацию о входящем запросе.

    • template: файл шаблона для рендеринга.

    • context: содержит переменные, которые будут доступны в шаблоне, обычно представленные в виде словаря.

Пример представления

Продолжая наш Список задач, вот как будет выглядеть наше представление:

def task_list(request):
    # Здесь размещается логика...
    return render(request, <template>, {'tasks': tasks})

Компонент шаблона

Шаблоны Django отвечают за отображение окончательного HTML-вывода в браузере. Они определяют, как данные должны быть представлены, используя комбинацию HTML и языка шаблонов Django.

Язык шаблонов Django включает использование тегов шаблона {% %} и переменных шаблона {{ }}, которые позволяют войти в режим Django в вашем HTML-шаблоне. В этом режиме вы можете получить доступ к переменным, определенным в ваших представлениях, и использовать управляющие структуры в вашем шаблоне.

Шаблоны также могут быть стилизованы с использованием CSS или любых из ваших любимых CSS-фреймворков, чтобы сделать ваш интерфейс пользователя более презентабельным.

Пример шаблона

Наш шаблон – это обычный файл HTML с языком шаблонов Django. Вот как будет выглядеть наш шаблон Списка задач:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>
</body>
</html>

В этом шаблоне:

  • Цикл for проходит по каждой задаче в списке tasks (помните, что он был передан как контекст в наши представления).

  • Для каждой задачи он выводит заголовок задачи title и ее статус completed (как “Done” или “Not Done”).

  • Если список tasks пуст, блок {% empty %} показывает запасное сообщение “No tasks available”.

Диаграмма, показывающая рабочий процесс MVT

Эта диаграмма показывает, как данные передаются в архитектуре MVT Django:

Реальный аналог MVT

Представьте, что вы приходите в ресторан и делаете заказ вашего любимого блюда. За кулисами в ресторане есть кулинарная книга, в которой описано, как готовить каждое блюдо. Шеф-повар использует рецепты, чтобы приготовить ваше блюдо точно так, как вы заказали. Когда оно готово, официант принесет вам блюдо в презентабельном виде.

Точно так же, как шеф-повар следует рецепту, чтобы создать блюдо, Представление использует Модель для сбора и обработки данных. Наконец, как официант, который доставляет блюдо, Шаблон гарантирует, что конечный результат представлен пользователю в ясном и увлекательном формате.

Сведение всего этого в один проект

Этот раздел проведет вас от начала до конца по настройке Списка задач, который мы использовали в качестве примера в статье. В конце у вас должно быть функциональное приложение с архитектурой MVT в полном разгаре.

Установите Python

Сначала убедитесь, что у вас установлен Python. Вы можете посетить официальный сайт Python, чтобы скачать последнюю версию Python.

Настройте проект и приложение Django

Затем установите Django. Вы можете установить его с помощью pip:

pip install django

Создайте папку и откройте ее в вашем любимом редакторе кода.

Создайте новый проект и приложение Django, выполнив следующие команды в вашем терминале одну за другой:

django-admin startproject myproject 
cd myproject
django-admin startapp myapp

Определите модель

В вашем myapp/models.py:

from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

Создайте форму

Нам нужна форма Django на основе модели Задача, поэтому мы создадим ее с помощью Django ModelForm.

В вашем myapp создайте файл, назовите его forms.py и вставьте этот код:

from django import forms
from .models import Task

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'completed']

В этом коде:

  • Task импортируется из .models.

  • class TaskForm(forms.ModelForm): Это создает новый класс с именем TaskForm, который является подклассом forms.ModelForm.

  • class Meta:: это специальный класс, используемый в ModelForm Django для настройки формы. Класс Meta сообщает Django, как создать форму, указывая связанную модель и поля, которые необходимо включить в форму.

  • model = Task: указывает модель, на основе которой создается форма. В данном случае форма основана на модели Task.

  • fields = ['title', 'description', 'completed']: указывает, какие поля из модели Task должны быть включены в форму. Это позволяет контролировать, какие поля модели отображаются в форме, и можно настроить включение только определенных полей, а не всех полей модели.

Создайте представление

В вашем myapp/views.py вставьте этот код:

from django.shortcuts import render,redirect
from .models import Task
from .forms import TaskForm

def task_list(request):
    tasks = Task.objects.all()    # Получение всех задач

    if request.method == 'POST':    # Обработка отправленных форм
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('task_list')  # Перенаправление для избежания дублирования отправок
    else:
        form = TaskForm()

    # Передача задач и формы в шаблон
    return render(request, 'task_list.html', {'tasks': tasks, 'form': form})

В этом представлении,

  • TaskForm импортируется из forms.

  • Код проверяет, является ли метод запроса POST, что указывает на то, что пользователь отправил форму.

  • Если метод POST, то создается экземпляр TaskForm, используя отправленные данные (request.POST).

  • Затем форма проверяется на валидность с помощью form.is_valid(), и если она валидна, форма сохраняется в базу данных.

  • После сохранения пользователь перенаправляется на страницу списка задач, чтобы избежать дублирования отправок.

Определение шаблона

В вашем каталоге myapp создайте папку templates. Внутри папки templates создайте файл с именем task_list.html. Нам нужно добавить элемент формы, который собирает ввод пользователя и отображает его в списке на пользовательском интерфейсе.

В HTML-файле task_list у нас есть:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>

    <h2>Add a New Task</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Add Task</button>
    </form>
</body>
</html>

В добавленном коде формы:

  • Мы создали HTML-форму с методом POST для отправки данных. Она включает {% csrf_token %} для защиты от атак CSRF.

  • Поля формы отображаются с помощью {{ form.as_p }}, который отображает каждое поле внутри тега <p>.

  • Наконец, предоставлена кнопка отправки с названием “Добавить задачу”, позволяющая пользователю отправить данные формы.

Структура папок

Достигнув этой точки, важно проверить, настроили ли вы свое приложение правильно. Вот как должна выглядеть структура вашей папки/файла:

└── 📁myproject
    └── 📁myapp
        └── 📁__pycache__
        └── 📁migrations
        └── 📁templates
            └── task_list.html
        └── __init__.py
        └── admin.py
        └── apps.py
        └── forms.py
        └── models.py
        └── tests.py
        └── urls.py
        └── views.py
    └── 📁myproject
        └── 📁__pycache__
        └── __init__.py
        └── asgi.py
        └── settings.py
        └── urls.py
        └── wsgi.py
    └── db.sqlite3
    └── manage.py

Настройка URL проекта

В вашем myproject/urls.py включите URL в ваш myapp:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
]

Добавление приложения в настройки проекта

Добавьте ваше myapp в список Установленных приложений в вашем myproject/settings.py:

INSTALLED_APPS = [
    'myapp',       # добавлено наше приложение myapp 
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Запуск сервера

Примените миграцию и запустите сервер, введя эти команды:

python manage.py migrate

python manage.py runserver

Посетите http://127.0.0.1:8000/ в вашем браузере, чтобы протестировать ваше приложение.

Финальный вид

Вот как выглядит наше приложение списка задач в браузере после добавления некоторых задач с помощью формы. Вы можете дальше улучшать стиль шаблона по своему усмотрению.

Заключение

В этой статье вы узнали о компонентах архитектуры MVT в Django, о том, как они взаимодействуют друг с другом, и как они делают веб-опыт более непрерывным. Мы также создали простой проект, чтобы увидеть, как это работает на практике, и я надеюсь, что теперь вы лучше это понимаете.

Если вам понравилась эта статья, вы можете следить за мной в X или связаться со мной в LinkedIn для получения дополнительных статей и публикаций по программированию.

Увидимся в следующий раз!