JavaRush /Курси /Модуль 3: Django /Динамічні URL в Django

Динамічні URL в Django

Модуль 3: Django
Рівень 3 , Лекція 6
Відкрита

У цій лекції ми розглянемо динамічні URL — один із найкорисніших інструментів Django для створення гнучких маршрутів.

Динамічні URL: що це і навіщо вони потрібні?

Пам'ятаєте часи, коли сайти складалися зі сторінок типу www.mysite.com/page1.html і www.mysite.com/page2.html? Як і технології ігор, що еволюціонували від піксельних стрілялок до сучасних 3D-шутерів, веб-розробка теж не стоїть на місці - статична маршрутизація давно стала історією. Сьогодні ми маємо справу з тисячами динамічних сторінок: профілі користувачів, картки товарів, статті в блогах – список можна продовжувати безкінечно.

Уявіть ситуацію: ви робите блог зі 100 статтями. Спробуєте створити окремий маршрут для кожної статті (blog/1, blog/2 і так далі)? Спойлер: це шлях до божевілля, а ваші колеги почнуть обходити вас за кілометр. На щастя, існують динамічні URL, які рятують нас від цього головного болю.

Динамічні URL – це крута штука, яка дозволяє передавати параметри прямо в адресному рядку і використовувати їх у представленнях.

Наприклад:

  • URL: /blog/42/
  • Представлення бере число 42 як ID статті і показує потрібний контент.

Основи динамічних URL

У Django динамічні маршрути задаються через спеціальні шаблони у функції path() (або re_path). У цих шаблонах змінні укладаються у дужки <>. Наприклад:

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<int:post_id>/', views.post_detail, name='post_detail'),
]

У цьому прикладі:

  • blog/<int:post_id>/ — це динамічний маршрут.
  • <int:post_id> вказує, що ми очікуємо цілочисельний параметр з ім'ям post_id.
  • Цей параметр буде переданий у функцію представлення post_detail.

Приклад створення динамічного маршруту

Крок 1. Визначимо маршрут у urls.py

Створимо маршрут для відображення профілю користувача, передаючи його ID через URL.

from django.urls import path
from . import views

urlpatterns = [
    path('user/<int:user_id>/', views.user_profile, name='user_profile'),
]

Крок 2. Напишемо представлення

Тепер наш маршрут має обробляти запити. Створюємо функцію представлення user_profile у файлі views.py.

from django.http import HttpResponse

# Представлення для відображення профілю користувача
def user_profile(request, user_id):
    return HttpResponse(f"Ви переглядаєте профіль користувача з ID: {user_id}")

Django автоматично витягує значення <int:user_id> з URL і передає його як аргумент функції представлення.

Крок 3. Перевіримо результат

Запустіть сервер: python manage.py runserver. Потім у браузері перейдіть на адресу http://127.0.0.1:8000/user/123/. Ви побачите повідомлення:

Ви переглядаєте профіль користувача з ID: 123

Давайте поаплодуємо собі! Ви щойно створили динамічний маршрут.

Типи динамічних змінних

Ще раз нагадаємо основні типи даних для динамічних змінних в Django (навряд чи ви їх запам'ятали з першого разу):

Тип Приклад Опис
str <str:name> Будь-який рядок
int <int:id> Ціле число
slug <slug:slug> Склади (літери, цифри, дефіси, підкреслення)
uuid <uuid:uuid> UUID (універсальний ідентифікатор)
path <path:path> Рядок із символами /

Якщо тип не вказано, Django за замовчуванням припускає str.

Приклад із різними типами маршрутів:

urlpatterns = [
    path('article/<slug:slug>/', views.article_detail, name='article_detail'),
    path('file/<path:file_path>/', views.file_view, name='file_view'),
    path('uuid/<uuid:doc_id>/', views.document_view, name='document_view'),
]

Використання в реальному проєкті: приклад блогу

Припустимо, у нас є таблиця з постами блогу. Нам потрібно зробити так, щоб кожен пост відкривався за адресою /blog/<id>/.

Модель Post

Створимо модель поста в models.py:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()

    def __str__(self):
        return self.title

Після цього не забудьте зробити міграції:

python manage.py makemigrations
python manage.py migrate

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

Тепер напишемо представлення, яке буде повертати дані поста за його ID:

from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from .models import Post

def post_detail(request, post_id):
    # Отримуємо об'єкт Post або повертаємо 404, якщо не знайдено
    post = get_object_or_404(Post, id=post_id)
    return HttpResponse(f"Title: {post.title}
Content: {post.content}")

Функція get_object_or_404 — це вбудований зручний інструмент Django, який автоматично викликає помилку 404, якщо об'єкт не знайдено. Це краще і безпечніше, ніж обробляти подібну логіку вручну.

Налаштовуємо маршрут

У urls.py додаємо маршрут для відображення постів:

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<int:post_id>/', views.post_detail, name='post_detail'),
]

Тепер, додавши кілька записів у базу даних, ви можете перейти на /blog/1/, /blog/2/, і побачити відповідні сторінки.

Отримання кількох параметрів з URL

Динамічні URL не обмежуються одним параметром. Ви можете передавати кілька параметрів. Наприклад:

urlpatterns = [
    path('category/<str:category_name>/post/<int:post_id>/', views.category_post, name='category_post'),
]

Представлення:

def category_post(request, category_name, post_id):
    return HttpResponse(f"Категорія: {category_name}, Пост ID: {post_id}")

Тепер, відкриваючи /category/python/post/42/, ви отримаєте:

Категорія: python, Пост ID: 42

Часті помилки та особливості

  1. Якщо певний маршрут не збігається із зазначеним форматом, Django поверне помилку 404. Наприклад, при використанні <int:id>, запит /user/abc/ викличе 404. Переконайтеся, що передаєте дані правильного типу.

  2. Якщо в urls.py є два однакових маршрути (наприклад, path('blog/<int:id>/') і path('blog/<str:id>/')), Django вибере перший підходящий за порядком. Будьте уважні та уникайте конфліктів.

  3. Динамічні параметри доступні тільки у представленнях, до яких прив'язаний маршрут. Неправильне використання змінних викличе TypeError, оскільки представлення очікує певні аргументи.

  4. Якщо ви використовуєте re_path, переконайтеся, що регулярний вираз написаний правильно. Невелика помилка може зламати весь маршрут.

Практичне завдання

  1. Додайте в проєкт маршрут /profile/<slug:username>/, який повертає привітальне повідомлення для користувача за його ім'ям.
  2. Реалізуйте маршрут /shop/<int:category_id>/<slug:product_name>/, який відображає інформацію про товар.
  3. Подумайте, як можна використовувати uuid у маршрутах для більш безпечної передачі даних (наприклад, для посилань на приватні ресурси).

Для любителів складнощів: додайте контроль на рівні маршрутизації, щоб обробити випадок, якщо користувач вказує неправильні параметри.

urlpatterns = [
    path('profile/<slug:username>/', views.user_greet, name='user_greet'),
    path('shop/<int:category_id>/<slug:product_name>/', views.product_detail, name='product_detail'),
]
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ