Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Latest commit

 

History

History
812 lines (509 loc) · 47.1 KB

lesson28.md

File metadata and controls

812 lines (509 loc) · 47.1 KB

Урок 28. Знакомство с Django

Как работает интернет, и что именно мы будем изучать?

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

На самом деле большая часть работы - это результат выполнения различных запросов, и в первую очередь - запросов по протоколу http (скорее, https, о чём мы поговорим значительно позже).

Когда вы набираете в браузере URL или просто переходите по закладкам или ссылкам, на самом деле, вы заставляете браузер создавать и отправлять GET http-запрос. А когда вводите имя пользователя и пароль, чаще всего после кнопки, например, "Войти", вы формируете и отправляете POST http-запрос.

Request-response, он же клиент-сервер

Чаще всего при работе с веб-ресурсами мы будем иметь дело с так называемым взаимодействием запрос-ответ, что на английском звучит как request-response.

А это значит, что у нас есть кто-то, кто "спрашивает", и кто-то, кто "отвечает".

Кто может спрашивать?

На самом деле спрашивать может любое устройство или приложение, которое способно сформировать http запрос, а в современном мире это уже почти любое устройство, включая чайники, часы и стиральные машины.

Но в самом распространённом варианте это всё-таки будут:

  • Веб-браузеры (Chrome, Mozilla, Opera, их мобильные аналоги и т. п.)
  • Приложения (Instagram, Telegram и т. п. Приложения бывают не только мобильные, но и для компьютера или планшета, и мы даже будем ими пользоваться в рамках курса)

Кто может отвечать?

Отвечать может только сервер. В отличие от задающего вопрос, отвечать может только специально подготовленный сервер. Сервером может являться любое электронное устройство, на котором можно запустить необходимый набор программ или команд. В рамках обучения вы будете запускать сервер прямо на ваших компьютерах, при разработке так обычно и делается, но реальные сайты и приложения обычно располагаются на специально подготовленных, изолированных или облачных компьютерах, и в случае веб-приложения на python это практически всегда будет компьютер с операционной системой Linux, зачем и как это настроить, мы поговорим ближе к концу нашего курса.

А бывает ли не клиент-сервер?

Бывает, но используется крайне редко, и для очень специфических случаев. Так что для нас не несёт полезной информации.

Краткое описание http запросов

Из чего состоит http запрос можно почитать тут, но, если вкратце, то из тела, где хранятся данные, и хедеров, где хранится служебная информация.

Метод GET

Используется для запроса содержимого указанного ресурса. Например, получить данные, файл или любую другую информацию, браузер (Chrome, Mozilla, etc.) при вводе url (https://ru.wikipedia.org/, https://www.youtube.com/watch?v=WdZJ-QUItHw&t=7974s) использует именно GET запрос, может передавать переменные в query параметре (в примере с YouTube ?v=WdZJ-QUItHw&t=7974s - это query параметры, первый параметр начинается с символа ?, следующий параметр добавляется при помощи символа &, в данном примере параметр - это словарь {'v': 'WdZJ-QUItHw', 't': '7974s'}).

Обычно не используется для отправки данных (query параметры чаще используются для уточнения того, что вы хотите получить, например, значения фильтров или каких-то системных параметров).

Например, получение комментариев к посту в блоге, или списка рекомендаций на YouTube, открытие любого сайта это уже GET запрос.

Метод POST

Применяется для передачи пользовательских данных заданному ресурсу. Если мы хотим ввести имя пользователя и пароль, обычно мы используем POST, потому что это передача пользовательских данных. Хотим оставить комментарий - POST, заказать товар из интернет-магазина - POST, и т. д. Практически всегда, когда мы отправляем пользовательские данные, это будет POST.

Методы PUT и PATCH

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

Метод DELETE

Используется для удаления объектов. Подробно рассмотрим в следующем блоке.

Методы TRACE, HEAD, OPTIONS и т. д.

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

Шаблон проектирования MVC

Для разработки сложных решений используются шаблоны проектирования (patterns).

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

Так вот, в программировании тоже все стандартные решения придумали за нас. Называются они паттерны, и вы уже слышали этот термин, когда обсуждали такие вещи как ООА\ООД\ООП.

В данный момент для нас с точки зрения создания веб-ресурсов самым важным из них является MVC (Model - View - Controller) (Модель - Отображение - Контроллер)

Что же это такое?

Это разделение обязанностей между тремя зависимыми блоками.

Давайте посмотрим на работу обычного ресторана.

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

Получается, что клиент видел только меню и конечное блюдо, но не видел повара или, тем более, склад с продуктами, но ожидаемый результат всё-таки получил.

Большая часть сайтов или приложений так же делится на три компонента, Model - View - Controller

Если рассматривать пример с рестораном, то зал, в котором находится клиент, его столик и его тарелка будут являться Отображением, оно же View, В случае с сайтом или приложением, этим элементом является всё что может увидеть пользователь.

Официант, который принимает заказ и выносит блюдо, является в этой аналогии http запросами и ответами. И общается только с Контроллером, он же Controller

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

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

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

Сегодня мы изучим, как именно формируется "меню" для Django, и что это вообще.

По этому же принципу работает и Django, но с немного другими названиями, паттерн называется MVT (Model - View - Template)

  • где View играет роль Controller, а Template роль View, но это точно такая же идея, изменились только названия блоков.

Что же такое все-таки Django?

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

Основной информационный ресурс Django

Наконец-то практика

Виртуальное окружение

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

Чтобы разные проекты не пересекались, можно использовать разные компьютеры для разных проектов, но не надо так делать :)

Существует возможность создать виртуальное окружение для каждого отдельного проекта. По сути, создаётся папка, в которую копируется сам интерпретатор python, вспомогательные системные файлы, и создаётся папка, куда будут устанавливаться все необходимые для конкретного проекта пакеты.

Консоль

Когда мы занимаемся программированием, нам очень часто необходимо использовать консоль, будь то Windows или Linux

В Windows, чтобы открыть терминал, необходимо нажать Win+R, и во всплывшем окне набрать cmd.

В Linux/Mac многое зависит от дистрибутива, но часто можно найти по поиску, по слову Terminal, или по клавишам Alt+T ( далеко не везде будет работать)

cd

Команда cd (Change Directory) позволяет изменить текущую папку. Мы можем указать ей как абсолютный cd /home/my_user, так и относительный cd my_images(находясь, допустим, в папке /home/my_user) пути.

Перейти на директорию уровнем выше cd .. (были в /home/my_user/my_images/ попали в /home/my_user/)

Перейти на директорию двумя уровнями выше cd ../.. (были в /home/my_user/my_images/ попали в /home)

Создание виртуального окружения

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

В консоли необходимо указать

python -m venv /path/to/new/virtual/environment

где /path/to/new/virtual/environment - путь к вашему виртуальному окружению (я создал себе папку, которую назвал environments, и уже непосредственно в ней создаю новые виртуальные окружения)

Активация и деактивация виртуального окружения

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

Для активации необходимо запустить активационный скрипт.

Windows

Для windows внутри папки с виртуальным окружением нам необходим файл activate в папке Scripts

Допустим вы находились в папке C:\Users\black>, и прописали команду python -m venv test_env, это создаст папку C:\Users\black\test_env, значит, чтобы запустить виртуальное окружение, нужно выполнить команду test_env\Scripts\activate

Linux/Mac

В этих операционных системах необходимо использовать команду source, применяя её к файлу activate в папке bin.

Допустим вы находились в папке /home/black/ и прописали команду python -m venv test_env, это создаст папку /home/black/test_env, значит, чтобы запустить виртуальное окружение, нужно выполнить команду source test_env/bin/activate

После чего в консоли перед курсором появится название виртуального окружения (test_env)(в наших примерах).

Чтобы деактивировать виртуальное окружение, для любых систем необходимо использовать команду deactivate

Создадим новый проект

Для создания проекта создаём виртуальное окружение и активируем его (описание выше).

После чего необходимо выполнить два действия:

  • Установить Django
  • Перейти в папку, где мы собираемся создать проект, в котором будем писать код.

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

Чтобы установить последнюю версию Django, необходимо выполнить команду:

pip install django

Если необходимо установить конкретную версию, нужно добавить ==x.y, например

pip install django==2.2

После установки django и перехода в папку, в которой вы собираетесь работать, необходимо создать проект, сделать это можно через такую команду:

django-admin startproject mysite

mysite - это название вашего проекта, может быть таким, как вам необходимо.

Эта команда создаёт новый проект, и заполняет его базово нужными файлами, давайте рассмотрим их.

Структура файлов:

mysite /
    manage.py
    mysite /
        __init__.py
        settings.py
        urls.py
        wsgi.py
        asgi.py

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

Внутри папки mysite:

__init__.py - пустой файл, который говорит Python-у, что этот каталог должен рассматриваться как пакет Python-а

settings.py - настройки и конфигурации проекта.

urls.py - URL-ы для этого проекта; «меню» вашего сайта на платформе Django.

wsgi.py - файл, отвечающий за входную точку сервера (позволяет запускать код как сайт), разберём почти в самом конце курса

asgi.py - файл, отвечающий за входную точку сервера асинхронно (позволяет запускать код как сайт), разберём почти в самом конце курса

Проверим работоспособность.

В консоли запустим локальный "сервер" из папки с нашим "сайтом" (в моём примере mysite)

**Необходимо находиться в консоли в той же папке, где находится manage.py с включённым виртуальным окружением.

python manage.py runserver

В консоли должна появиться примерно такая надпись.

Не закрывая консоль (сервер должен работать), открываем в браузере http://127.0.0.1:8000/

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

А браузер будет клиентом (помним о взаимодействии клиент-сервер? )

При таком подходе наш компьютер сразу является и клиентом (браузер), и сервером (скрипт запущенный в консоли).

127.0.0.1 - это локальный хост (обращаться к вашему же собственному компьютеру), а :8000 - это номер порта, на котором запущен процесс (если не указывать порт, то по умолчанию будет использоваться 80 порт для http и 443 для https). Когда вы открываете любой сайт, на самом деле, вы скрытым образом указываете порт. Для разработки часто используют те порты, на которых точно не будет ничего полезного (других программ работающих на вашем компьютере), для Django по умолчанию используется порт 8000, если нужно, его можно изменить, но обычно в этом нет необходимости. 127.0.0.1 можно заменить на 0.0.0.0 или слово localhost, все три варианта практически взаимозаменяемы.

Если вы всё сделали правильно, то в браузере должны увидеть, что-то такое:

Создаём приложение

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

Через консоль и уже известную нам manage.py создадим приложение

python manage.py startapp myapp

Команда создаст вам папку с вашим приложением, давайте разберем её подробнее.

myapp/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

__init__.py - пустой файл, который говорит Python-у, что этот каталог должен рассматриваться как пакет Python-а

admin.py - заготовка под страницу для администратора, удобный встроенный инструмент, разберём на следующих занятиях

apps.py - информация о приложении, просто смиритесь, что этот файл есть.

папка migrations - тут будут миграции базы данных.

models.py - модели.

tests.py - тесты.

views.py - контроллер приложения.

Наш первый URL

Теперь у нас всё готово для того, чтобы начать создавать наш сайт. Сегодня мы будем разбираться, как работают urls.

При любом запросе к запущенному Django приложению при обработке запроса запущенный сервер в первую очередь заходит в файл settings.py и ищет там переменную URL_CONF, по умолчанию там будет указан файл urls.py, который находится в той же папке, где и settings.py.

Внутри этого файла Django ожидает наличие переменной urlpatterns, которая содержит коллекцию (например, список), состоящую из специальных объектов path или re_path.

На самом деле эти объекты появились в Django только после версии, 2.0, сейчас актуальная версия это 4.2, но потенциально вы можете встретить и версии ниже, например, 1.11, поэтому ниже мы разберем и более старые варианты урлов. До 2.0 там были коллекции из объектов url, и все они работали на регулярных выражениях, о них позже.

Вся основная логика обработки запросов пишется в приложениях в файлах views.py, у нас всего одно приложение, поэтому всю логику (сегодня она будет простейшая) мы будем писать в файл myapp/views.py.

Для начала изменим файл views.py

# mysite/myapp/views.py
from django.http import HttpResponse


# Поздравляю, это ваш первый контроллер, который может принять запрос и отдать ответ с текстом, больше ничего
def main(request):
    return HttpResponse("Hey! It's your main view!!")

Мы создали функцию, которая принимает один параметр request и возвращает объект HttpResponse.

Это нужно, потому что вся веб-инфраструктура работает на request-response системе, мы тоже не будем её нарушать, и будем принимать запросы и возвращать ответы.

Объект HttpResponse мы импортировали из Django, и на данном этапе нас совершенно не интересует, как он работает, как и то, что именно находится в переменной request.

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

Для использования этого контроллера в качестве логики, он должен быть описан в файле urls.py:

# mysite/mysite/urls.py
from django.urls import path
from myapp.views import main

urlpatterns = [
    path('', main)
]

Мы импортировали path из Django и метод main из нашего views.py

Объект path принимает два обязательных параметра:

  • Строка, которая содержит путь
  • Обработчик, что именно должно происходить при запросе по такому пути.

Строка пути

Строка, которая указывает, как именно можно выполнить запрос к данному url.

Например, если указать там пустую строку и запустить сервер на локалхосте на 8000 порту, то запросы нужно выполнять по адресу 127.0.0.1:8000/

Если указать там, например, super_cool_path, то обращаться нужно было бы к 127.0.0.1:8000/super_cool_path/

Не может содержать пробелов, может содержать /

Обработчик

Что угодно, что можно вызвать (), на данном этапе это функции, дальше мы будем использовать классы. При вызове добавляем в качестве аргумента переменную request.

Объект path так же может принимать атрибут name=, который нужен дня автоматической генерации адресов, будем изучать на следующем занятии, и некоторые другие необязательные атрибуты.

Если мы перезапустим (ну или запустим) сервер и откроем страницу, то мы увидим, что-то такое:

Список урлов проекта называется routing (маршрутизация). Маршрутизацию можно строить так, как вам удобно, или как того требует задание.

Напишем еще один контроллер, для "другой" страницы. В файле myapp/views.py

from django.http import HttpResponse


def main(request):
    return HttpResponse("Hey! It's your main view!!")


def another(request):
    return HttpResponse("It's another page!!")

А в файле mysite/urls.py импортируем эти функции и добавим маршрут в список, чтобы получилось так:

from django.urls import path
from myapp.views import main, another

urlpatterns = [
    path('', main),
    path('some_url/', another)
]

То, что написано в строке до контроллера - это путь к урлу, а значит, чтобы увидеть обработку этого контроллера, нужно открыть страницу http:/127.0.0.1:8000/some_url/

Открываем эту страницу и видим результат:

Урлы с параметрами

Урл может заведомо принимать параметры, самый простой способ - это описание параметра через синтаксис <type:variable>

Обновим наш urls.py:

from django.urls import path
from myapp.views import main, another, main_article, uniq_article, article

urlpatterns = [
    path('', main),
    path('some_url/', another),
    path('article/', main_article, name='main_article'),
    path('article/33/', uniq_article, name='unique_article'),
    path('article/<int:article_id>/', article, name='article'),
]

Обратите внимание, часть урлов теперь имеет параметр name, он понадобится на следующем занятии.

А в последнем url мы указали параметр int:article_id, значение до двоеточия - это тип данных, принимаемых параметром, а после двоеточия - это имя параметра, который можно будет использовать в контроллере, чтобы получить значение этого параметра.

Всего существует 5 таких типов:

  • str - ищет непустую строку, без символа /

  • int - ноль или любое положительное число.

  • slug - по сути, это тоже строка, которая состоит из букв, цифр, нижних подчеркиваний, дефисов, символов плюс, например, building-your-1st-django-site отличается от обычной строки тем, что обычно этот урл берет данные из уже существующих данных. Слагом может быть название статьи, уникальный номер товара и т. д.

  • uuid - ищет соответствие UUID, это специальный формат, состоящий из шестнадцатеричных цифр, букв и дефисов, дефисы должны быть обязательно, буквы в нижнем регистре. Например, 075194d3-6885-417e-a8a8-6c931e272f00.

  • path - строка с одним или несколькими символами /

Обратите внимание, что url `article/33/` попадает так же и под `article/<int:article_id>/`, потому что 33 - это тоже цифра, в этом случае будет использован тот, который находится в списке первым. Урлы считываются сверху вниз

Изменим myapp/views.py:

from django.http import HttpResponse


def main(request):
    return HttpResponse("Hey! It's your main view!!")


def another(request):
    return HttpResponse("It's another page!!")


def main_article(request):
    return HttpResponse('There will be a list with articles')


def uniq_article(request):
    return HttpResponse('This is a unique answer for a unique value')


def article(request, article_id):
    return HttpResponse(f"This is article #{article_id}.")

Обратите внимание, в функцию article я добавил параметр article_id для получения значения в контроллере.

Давайте посмотрим на результат при переходе на разные страницы.

Последнее - это пример работы, если url не был описан (всем известная страница 404, в debug режиме она может рассказать много подробностей об ошибке). В данном примере ошибка говорит о том, что контроллера для указанного запроса не существует.

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

views.py

from django.http import HttpResponse


def main(request):
    return HttpResponse("Hey! It's your main view!!")


def another(request):
    return HttpResponse("It's another page!!")


def main_article(request):
    return HttpResponse('There will be a list with articles')


def uniq_article(request):
    return HttpResponse('This is a unique answer for a unique value')


def article(request, article_id, name=''):
    return HttpResponse(
        "This is an article #{}. {}".format(article_id, "Name of this article is {}".format(
            name) if name else "This is unnamed article"))

urls.py

from django.urls import path
from myapp.views import main, another, main_article, uniq_article, article

urlpatterns = [
    path('', main),
    path('some_url/', another),
    path('article/', main_article, name='main_article'),
    path('article/33/', uniq_article, name='unique_article'),
    path('article/<int:article_id>/', article, name='article'),
    path('article/<int:article_id>/<slug:name>', article, name='article_name'),
]

Результаты некоторых запросов:

include

На самом деле path может принимать не только обработчик, но и специальный параметр include, который позволяет добавить urls из другого файла к основному.

Например, вы видите, что у нас есть 4 урла, которые начинаются на article/, а значит, что удобным вариантом было бы вынести urls в отдельный файл. Обычно такие файлы создаются на уровне приложений, а основной файл с urls содержит только команды include.

Чтобы перенести часть urls, нам необходимо создать файл urls.py в приложении myapp (на самом деле мы могли и назвать его как угодно, и сложить его куда угодно, но так просто удобнее и читаемее), и обязательно в этом файле создать переменную urlpatterns, содержащую коллекцию url.

Посмотрим на измененные и добавленные файлы:

myapp/urls.py

from django.urls import path
from .views import main_article, uniq_article, article

urlpatterns = [
    path('', main_article, name='main_article'),
    path('33/', uniq_article, name='unique_article'),
    path('<int:article_id>/', article, name='article'),
    path('<int:article_id>/<slug:name>', article, name='article_name'),
]

mysite/urls.py

from django.urls import path, include
from myapp.views import main, another

urlpatterns = [
    path('', main),
    path('some_url/', another),
    path('article/', include('myapp.urls'))
]

После этого изменения ни один url не изменился - они просто стали по другому располагаться, в случае с 4 urls не до конца понятно, зачем это может быть нужно, но когда у нас существует 20 приложений и в них 5000+ url, структура становится очень важна, чтобы ничего не потерять. Поэтому правилом хорошего тона для Django кода считается создание файла с urls в каждом приложении, а в основном файле хранить только команды include на них. (Если сделать url path('', include('app.urls')), то можно перенести и те 2 url, которые мы сейчас оставили в основных url.)

re_path

Регулярные выражения

Как говорит нам википедия Регуля́рные выраже́ния ( англ. regular expressions) — это используемый в компьютерных программах, работающих с текстом, формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов (символов-джокеров, англ. wildcard characters). Для поиска используется строка-образец (англ. pattern, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска. Для манипуляций с текстом дополнительно задаётся строка замены, которая также может содержать в себе специальные символы.

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

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

Предположим, что нам нужно указать в качестве части урла три цифры и хотя бы 2 буквы (123blabla, 432fo,111aaaaa и т. д., но 12asd не подходило)

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

Получаем необходимое регулярное выражение:

Теперь давайте попробуем использовать его в url

mysite/urls.py:

from django.urls import path, include, re_path
from myapp.views import main, another, regex

urlpatterns = [
    path('', main),
    path('some_url/', another),
    path('article/', include('myapp.urls')),
    re_path('\d{3}[a-zA-Z]{2,}', regex),
]

views.py

from django.http import HttpResponse


def main(request):
    return HttpResponse("Hey! It's your main view!!")


def another(request):
    return HttpResponse("It's another page!!")


def main_article(request):
    return HttpResponse('There will be a list with articles')


def uniq_article(request):
    return HttpResponse('This is a unique answer for a unique value')


def article(request, article_id, name=''):
    return HttpResponse(
        "This is an article #{}. {}".format(article_id, "Name of this article is {}".format(
            name) if name else "This is unnamed article"))


def regex(request):
    return HttpResponse("It's regexp")

Обратите внимание, мы используем не path, a re_path.

Такой url уже будет работать.

Но как нам получить значение именно этого регулярного выражения? Как бы не было ужасно, но завернуть его в другое регулярное выражение.

И после этого не забыть получить его в контроллере.

mysite/urls.py

from django.urls import path, include, re_path
from myapp.views import main, another, regex

urlpatterns = [
    path('', main),
    path('some_url/', another),
    path('article/', include('myapp.urls')),
    re_path(r'^(?P<text>\d{3}[a-zA-Z]{2,}$)', regex),
]

views.py

from django.http import HttpResponse


def main(request):
    return HttpResponse("Hey! It's your main view!!")


def another(request):
    return HttpResponse("It's another page!!")


def main_article(request):
    return HttpResponse('There will be a list with articles')


def uniq_article(request):
    return HttpResponse('This is a unique answer for a unique value')


def article(request, article_id, name=''):
    return HttpResponse(
        "This is an article #{}. {}".format(article_id, "Name of this article is {}".format(
            name) if name else "This is unnamed article"))


def regex(request, text):
    return HttpResponse(f"It's regexp with text: {text}")

Мы получили данные из урла.

Бывают и более сложные конструкции, рассмотрите их по вот этой ссылке

На практике редко встречаются более сложные конструкции, но Django представляет нам такую возможность.

Практика / домашнее задание:

Вся домашка на ближайшие много занятий описана вот тут:

https://edu-python-course.github.io/_build/html/uk/appx/blog/spec.html#challenge-functional-views

Там прописаны все задачи, разбитые на подзадачи, чтобы собрать их в один цельный проект.