Django 5 для начинающих

Прогресс по курсу:  9/1004

2.4 Диспетчер URL, часть 1.
4 из 14 шагов пройдено
0 из 42 баллов  получено

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

Функции-представления могут принимать параметры, через которые могут передаваться различные данные. Подобные параметры передаются в адресе URL.

http://127.0.0.1:8000/user/Tom/38/

Например, в этом запросе последние два сегмента Tom/38/ могут представлять параметры URL, которые могут быть связанны с параметрами функции-представления через систему маршрутизации. Подобные параметры еще можно назвать параметрами маршрута.

Определение параметров через функцию path

Добавим в файл views.py новую функцию user:

from django.http import HttpResponse


def index(request):
    return HttpResponse('<h2>Главная</h2>')


def about(request, name, age):
    return HttpResponse(f'''
        <h2>О пользователе</h2>
        <p>Имя: {name}</p>
        <p>Возраст: {age}</p>
    ''')


def contact(request):
    return HttpResponse('<h2>Контакты</h2>')


def user(request, name):
    return HttpResponse(f'<h2>Имя: {name}</h2>')

В данном случае функция user имеет два параметра. Для второго параметра - name мы будем получать данные из строки запроса. То есть это будет параметр маршрута. И как любой другой параметр мы сможем использовать его внутри функции.

Тогда в файле urls.py нам нужно написать следующий код:

from django.urls import path, re_path
from blog import views

urlpatterns = [
    path('', views.index),
    path('about/', views.about, kwargs={'name': 'Tom', 'age': 38}),
    re_path(r'^contact/', views.contact),
    path('user/<str:name>/', views.user),
]

Для маршрута функции user здесь определен параметр name (который соответствует параметру name функции views.user).

Параметры заключаются в угловые скобки в формате <спецификатор:название_параметра>.

Например, здесь параметр name имеет спецификатор str.


По умолчанию Django предоставляет следующие спецификаторы:

  • str: соответствует любой строке за исключением символа /. Если спецификатор не указан, то используется по умолчанию.
  • int: соответствует любому положительному числу.
  • slug: соответствует последовательности буквенных символов ASCII, цифр, дефиса и символа подчеркивания, например: building-your-1st-django-site.
  • uuid: соответствует идентификатору UUID, например: 075194d3-6885-417e-a8a8-6c931e272f00.
  • path: соответствует любой строке, которая также может включать символ / в отличие от спецификатора str.


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

Запустим приложение, обратимся к функции views.user, например, с помощью запроса http://127.0.0.1:8000/user/Tom, и через строку запроса мы сможем передать значение для параметра name:

 

А если мы перейдем http://127.0.0.1:8000/user/Bob

Подобным образом можно определить и большее количество параметров.
Например, добавим второй параметр в функцию user в views.py:

def user(request, name, age):
    return HttpResponse(f'<h2>Имя: {name} Возраст:{age}</h2>')

А в файле urls.py добавим в маршрут параметр age:

path('user/<str:name>/<int:age>/', views.user),

Предполагается, что параметр age будет представлять число, поэтому для него используется спецификатор int.
В этом случае мы можем обратиться к функции user, например, с помощью запроса http://127.0.0.1:8000/user/Tom/38:

В этом случае сегмент /Tom/ будет сопоставлен с параметром name, а /38 - с параметром age:

В примере выше использовались два параметра, но что, если мы не передадим для одного или обоих параметров значения?

В этом случае мы получим ошибку. Параметры маршрута являются частью шаблона URL. Соответственно если в строке запроса не передаются значения для параметров, такой запрос не соответствует маршруту. Поэтому Django не сможет найти нужный маршрут для обработки запроса, и мы получим ошибку 404 (ресурс не найден).

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

Так, для функции user в views.py определим значения для параметров по умолчанию:

def user(request, name='Undefined', age=0):
    return HttpResponse(f'<h2>Имя: {name} Возраст: {age}</h2>')

В данном случае, если для параметра name не передается значение, то он получает в качестве значения строку Undefined. Для параметра age значение по умолчанию 0.

В этом случае для функции user в файле urls.py надо определить дополнительные маршруты, которые не учитывают необязательные параметры:

from django.urls import path, re_path
from blog import views

urlpatterns = [
    path('', views.index),
    path('about/', views.about, kwargs={'name': 'Tom', 'age': 38}),
    re_path(r'^contact/', views.contact),
    path('user/<str:name>/<int:age>/', views.user),
    path('user/<str:name>/', views.user),
    path('user/', views.user),
]

Теперь при переходе на страницу http://127.0.0.1:8000/user/Tom/38 мы увидим сообщение Имя: Tom, Возраст: 38,
а при переходе по ссылке http://127.0.0.1:8000/user/Tom будет сообщение Имя: Tom, Возраст: 0, так как будет подставлено значение по умолчанию. А при переходе http://127.0.0.1:8000/user/ мы увидим значения по умолчанию, это Имя: Undefined, Возраст: 0


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

так классно сразу видеть результат)))

А почему не определен еще и маршрут на случай, если значение age передано, а name нет, например:

path("user/<int:age>/", views.user)?

Или такого делать нельзя?

@Агаси_Мироян, можно и такой маршрут добавить, но какой в этом смысл, зачем возраст без имени пользователя?

@Дмитрий_Селезнев, ну, с точки зрения логики, может и нет смысла, просто хотелось знать возможно ли такое с точки зрения джанго. Оказывается, возможно.