Що треба знати при розробці на фреймворку Django?
Вступ
Django — це високопродуктивний веб-фреймворк на Python, який заохочує швидку розробку та чистий, прагматичний дизайн. Побудований за принципом "батарейки в комплекті" (batteries-included), він надає розробникам все необхідне для створення складних, масштабованих веб-додатків з мінімальними зусиллями. Від автентифікації користувачів до ORM та адміністративної панелі — Django покриває більшість потреб сучасного веб-проекту.
У цій статті ми детально розглянемо ключові аспекти Django, які необхідно знати кожному розробнику, щоб ефективно використовувати цей фреймворк. Ми пройдемося по його архітектурі, основним компонентам, найкращим практикам та надамо приклади, які допоможуть вам швидко освоїти матеріал.
Архітектура Django: MVT (Model-View-Template)
Django дотримується архітектурного патерну MVT (Model-View-Template), який є варіацією добре відомого MVC (Model-View-Controller). У цьому контексті:
- Model (Модель): Визначає структуру даних, керує їх збереженням, отриманням, оновленням та видаленням (CRUD-операції). Це ваша єдина, авторитетна джерело інформації про дані. Моделі в Django взаємодіють з базою даних через ORM (Object-Relational Mapper).
- View (Представлення): Містить логіку, яка отримує HTTP-запит, взаємодіє з Моделлю для отримання або зміни даних, а потім передає їх у шаблон для відображення. Представлення визначає, які дані будуть показані користувачу.
- Template (Шаблон): Відповідає за візуальне представлення даних. Шаблони Django використовують свій власний синтаксис для вбудовування динамічного вмісту у статичні HTML-структури.
Хоча це і називається MVT, View у Django більше схожий на Controller з MVC (він керує логікою), а Template — це View (відображення). Model залишається Model.
Приклад: Проста структура проекту
Створимо базову структуру Django-проекту та додамо до нього просту програму (app).
# Створюємо новий проект Django
django-admin startproject myproject
# Переходимо в директорію проекту
cd myproject
# Створюємо програму blog
python manage.py startapp blog
Після цих кроків у вас буде наступна структура:
myproject/
├── manage.py
├── myproject/
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py # Налаштування проекту
│ ├── urls.py # Головні URL-маршрути проекту
│ └── wsgi.py
└── blog/
├── migrations/
│ └── __init__.py
├── __init__.py
├── admin.py # Реєстрація моделей для адмін-панелі
├── apps.py # Конфігурація програми
├── models.py # Визначення моделей даних
├── tests.py # Тести для програми
└── views.py # Логіка обробки запитів (представлення)
ORM Django: Моделі даних
Django ORM (Object-Relational Mapper) дозволяє вам взаємодіяти з базою даних за допомогою Python-класів, замість того, щоб писати SQL-запити вручну. Кожен клас моделі представляє таблицю в базі даних, а кожен атрибут класу — стовпець цієї таблиці.
Визначення Моделі
Розглянемо приклад моделі Post для блогу у файлі blog/models.py.
# blog/models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique_for_date='publish')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
class Meta:
ordering = ('-publish',) # Сортування за датою публікації
indexes = [
models.Index(fields=['-publish']),
]
def __str__(self):
return self.title
Пояснення полів:
CharField,TextField,DateTimeField: Базові типи полів.SlugField: Створює зручний для URL рядок.unique_for_dateгарантує унікальність slug в межах дати публікації.ForeignKey: Визначає зв'язок "багато до одного" з моделлюUser(вбудована модель користувача Django).on_delete=models.CASCADEозначає, що при видаленні користувача, пов'язані пости також будуть видалені.default=timezone.now: Встановлює значення за замовчуванням (поточний час) при створенні об'єкта.auto_now_add=True: Автоматично встановлює дату/час при першому створенні об'єкта.auto_now=True: Автоматично оновлює дату/час при кожному збереженні об'єкта.STATUS_CHOICES: Визначає можливі варіанти для поляstatus.Meta.ordering: Визначає порядок сортування за замовчуванням для запитів до цієї моделі.Meta.indexes: Дозволяє створювати індекси для полів бази даних, що прискорює пошук.
Міграції Бази Даних
Після визначення або зміни моделей, вам потрібно створити та застосувати міграції.
# Створити міграції (генерує файли у blog/migrations/)
python manage.py makemigrations
# Застосувати міграції до бази даних
python manage.py migrate
Ці команди створюють таблиці в базі даних, що відповідають вашим моделям.
Представлення (Views): Обробка запитів
Представлення в Django — це функції або класи, які отримують HTTP-запит і повертають HTTP-відповідь. Вони містять логіку вашого веб-додатку.
Функціональні Представлення
Це найпростіший спосіб написання представлень.
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.objects.filter(status='published').order_by('-publish')
return render(request, 'blog/post/list.html', {'posts': posts})
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request, 'blog/post/detail.html', {'post': post})
render(): Зручна функція, яка завантажує шаблон, передає йому контекст і повертаєHttpResponseз відрендереним шаблоном.get_object_or_404(): Отримує об'єкт за заданими параметрами або генеруєHttp404(сторінка не знайдена).
Класові Представлення (Class-Based Views - CBV)
CBV надають більш структурований і багаторазовий підхід. Django має багато вбудованих CBV, які спрощують типові операції.
# blog/views.py (продовження)
from django.views.generic import ListView, DetailView
class PostListView(ListView):
queryset = Post.objects.filter(status='published')
context_object_name = 'posts' # Ім'я змінної контексту, що передається в шаблон
template_name = 'blog/post/list.html'
paginate_by = 10 # Пагінація: 10 постів на сторінку
class PostDetailView(DetailView):
queryset = Post.objects.filter(status='published')
context_object_name = 'post'
template_name = 'blog/post/detail.html'
slug_field = 'slug' # Поле моделі, яке використовується для slug
# Параметри URL-маршруту (year, month, day) автоматично фільтруються за допомогою get_object_or_404 в DetailView
Маршрутизація (URLs): Підключення представлень
urls.py файли відповідають за зіставлення URL-адрес з відповідними представленнями. У Django є головний urls.py для проекту і окремі urls.py для кожної програми.
Головний urls.py проекту
# myproject/myproject/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # Підключаємо URL-и програми blog
]
path(): Функція для визначення URL-маршруту.include(): Дозволяє включати URL-маршрути з інших файлівurls.py. Це допомагає організувати маршрутизацію.
urls.py програми
# myproject/blog/urls.py
from django.urls import path
from . import views
from .views import PostListView, PostDetailView
app_name = 'blog' # Простір імен для URL-ів
urlpatterns = [
# Функціональні представлення
# path('', views.post_list, name='post_list'),
# path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
# Класові представлення
path('', PostListView.as_view(), name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
]
app_name: Дозволяє використовувати іменовані URL-и, наприкладblog:post_list.<int:year>: Конвертер для цілих чисел.<slug:post>/<slug:slug>: Конвертер для slug-рядків.PostListView.as_view(): Метод для використання класових представлень в URL-маршрутах.
Шаблони (Templates): Відображення даних
Система шаблонів Django дозволяє відокремити логіку від презентації. Шаблони — це звичайні HTML-файли з додаванням спеціальних тегів та фільтрів Django.
Налаштування Шляхів до Шаблонів
Переконайтеся, що ваш settings.py налаштований на пошук шаблонів.
# myproject/myproject/settings.py
# ...
TEMPLATES = [
{
# ...
'DIRS': [BASE_DIR / 'templates'], # Додайте шлях до глобальних шаблонів
'APP_DIRS': True, # Дозволяє Django шукати шаблони всередині директорій app/templates/
# ...
},
]
# ...
Приклад Шаблону list.html
Створіть файл myproject/blog/templates/blog/post/list.html (або myproject/templates/blog/post/list.html якщо використовуєте глобальну директорію для шаблонів).
<!-- myproject/blog/templates/blog/post/list.html -->
{% extends "base.html" %} {# Успадкування від базового шаблону #}
{% block title %}Мій Блог{% endblock %}
{% block content %}
<h1>Пости блогу</h1>
{% for post in posts %}
<div class="post">
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Опубліковано {{ post.publish|date:"F d, Y" }} автором {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }} {# Фільтри шаблонів #}
</div>
{% empty %}
<p>Наразі немає постів.</p>
{% endfor %}
{# Пагінація #}
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« перша</a>
<a href="?page={{ page_obj.previous_page_number }}">попередня</a>
{% endif %}
<span class="current">
Сторінка {{ page_obj.number }} з {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">наступна</a>
<a href="?page={{ page_obj.paginator.num_pages }}">остання »</a>
{% endif %}
</span>
</div>
{% endif %}
{% endblock %}
Ключові елементи шаблонів Django:
{% extends "base.html" %}: Розширює базовий шаблонbase.html, який містить загальну структуру сторінки (хедер, футер, меню).{% block title %} ... {% endblock %}: Визначає блоки вмісту, які можуть бути перевизначені дочірніми шаблонами.{{ variable }}: Виводить значення змінної.{{ variable|filter }}: Застосовує фільтр до змінної (наприклад,date:"F d, Y"форматує дату,truncatewords:30обрізає текст до 30 слів).{% for item in list %} ... {% empty %} ... {% endfor %}: Цикл для ітерації по списку. Блокemptyвідображається, якщо список порожній.{% if condition %} ... {% endif %}: Умовні конструкції.is_paginated,page_obj: Змінні контексту, що надаютьсяListViewдля пагінації.
Адміністративна панель Django
Django поставляється з потужною і повністю функціональною адміністративною панеллю, яка дозволяє легко керувати даними ваших моделей. Щоб використовувати її, вам потрібно зареєструвати ваші моделі.
Реєстрація Моделі в Адмін-панелі
Відкрийте blog/admin.py та зареєструйте вашу модель Post.
# blog/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'author', 'publish', 'status')
list_filter = ('status', 'created', 'publish', 'author')
search_fields = ('title', 'body')
prepopulated_fields = {'slug': ('title',)} # Автоматично заповнює slug з title
raw_id_fields = ('author',) # Зручний віджет для вибору автора
date_hierarchy = 'publish'
ordering = ('status', 'publish')
Створення Суперкористувача
Щоб отримати доступ до адмін-панелі, вам потрібно створити суперкористувача.
python manage.py createsuperuser
Після цього ви зможете зайти на http://127.0.0.1:8000/admin/ та керувати вашими постами.
Налаштування та Конфігурація
Файл myproject/myproject/settings.py містить всі налаштування вашого проекту.
Важливі Налаштування
INSTALLED_APPS: Список програм, які активовані у вашому проекті. Ваша програмаblogповинна бути тут.DATABASES: Налаштування підключення до бази даних. За замовчуванням Django використовує SQLite.STATIC_URL,STATIC_ROOT,MEDIA_URL,MEDIA_ROOT: Налаштування для статичних файлів (CSS, JS, зображення) та медіа-файлів (завантажені користувачами).TIME_ZONE,USE_TZ: Налаштування часових поясів.SECRET_KEY: Секретний ключ для безпеки. Його потрібно тримати в таємниці та не використовувати в продакшені те, що згенерувавstartproject.
REST API з Django REST Framework (DRF)
Хоча Django сам по собі є повноцінним фреймворком для веб-розробки, часто виникає потреба у створенні RESTful API. Для цього існує потужна бібліотека — Django REST Framework (DRF).
Встановлення DRF
pip install djangorestframework
Додайте rest_framework до INSTALLED_APPS у settings.py.
Приклад API для Post
# blog/serializers.py (створіть цей файл)
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'slug', 'author', 'body', 'publish', 'status']
# blog/views.py (додайте)
from rest_framework import generics
class PostListAPIView(generics.ListCreateAPIView):
queryset = Post.objects.filter(status='published')
serializer_class = PostSerializer
class PostDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.filter(status='published')
serializer_class = PostSerializer
lookup_field = 'slug' # Використовувати slug для пошуку, а не PK
# blog/urls.py (додайте)
from django.urls import path
from .views import PostListAPIView, PostDetailAPIView
urlpatterns = [
# ... інші маршрути ...
path('api/posts/', PostListAPIView.as_view(), name='post_list_api'),
path('api/posts/<slug:slug>/', PostDetailAPIView.as_view(), name='post_detail_api'),
]
DRF значно спрощує створення API, надаючи серіалізатори для перетворення моделей у JSON/XML та готові класові представлення для стандартних CRUD-операцій.
Найкращі Практики та Поради
- Розділяйте Логіку: Використовуйте принцип єдиної відповідальності. Моделі для даних, представлення для логіки, шаблони для презентації.
- Використовуйте CBV: Для типових операцій (CRUD) класові представлення значно зменшують кількість коду.
- Тести: Завжди пишіть тести. Django має вбудований фреймворк для тестування.
- Безпека: Вивчайте документацію Django з безпеки. Фреймворк надає багато вбудованих засобів захисту (CSRF, XSS, SQL-ін'єкції), але їх потрібно правильно використовувати.
- Налаштування
settings.py: Використовуйте змінні середовища для чутливих даних (наприклад,SECRET_KEY,DATABASE_URL) у продакшені. Бібліотеки, такі якpython-decoupleабоdjango-environ, можуть допомогти. - Статичні та Медіа-файли: Правильно налаштовуйте
STATIC_URL,STATIC_ROOT,MEDIA_URL,MEDIA_ROOTтаcollectstaticдля продакшену. - Форми: Використовуйте форми Django для обробки введення користувача. Вони надають валідацію та рендеринг.
- Документація: Документація Django є однією з найкращих у світі. Завжди звертайтеся до неї.
- Спільнота: Активно використовуйте ресурси спільноти (Stack Overflow, форуми, групи).
Висновок
Django — це потужний та багатофункціональний фреймворк, який дозволяє швидко та ефективно створювати веб-додатки будь-якої складності. Розуміння його архітектури MVT, вміння працювати з ORM, представленнями, URL-маршрутами та шаблонами є фундаментальними для успішної розробки.
Використання додаткових інструментів, таких як Django REST Framework, розширює можливості Django, дозволяючи створювати повноцінні бекенди для SPA або мобільних додатків. Дотримуючись найкращих практик, ви зможете писати чистий, підтримуваний та безпечний код, що відповідає сучасним стандартам веб-розробки.
Пам'ятайте, що постійне навчання та практика — ключ до освоєння будь-якого фреймворку. Почніть з малого проекту, експериментуйте з різними компонентами Django, і ви швидко станете вправним розробником на цьому чудовому фреймворку.