Программа курса:
Параметры представлений
Представления-функции могут обрабатывать разные данные, которые передаются через их параметры. Эти параметры передаются в URL-адресе.
Рассмотрим следующий URL-адрес:
http://127.0.0.1:8000/user/Tom/38/
В этом URL-адресе последние два сегмента 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
нам необходимо получать из запрошенного URL-адреса. Следовательно параметр name
будет являться параметром маршрута. Соответственно как любой другой параметр мы сможем использовать его внутри функции.
Добавим в файл urls.py
маршрут для функции user()
:
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/<str:name>/'
указан параметр name
, который будет извлечён из URL-адреса и передан в функцию user()
в виде параметра с таким же именем - name
.
Параметры в шаблоне пути обрамляются символами <
и >
в виде формата: <спецификатор:название_параметра>
.
В этом примере для параметра name
указан спецификатор str
.
По умолчанию Django предоставляет следующие спецификаторы:
str
: соответствует любой строке за исключением символа/
. Если спецификатор не указан, то данный спецификатор используется по умолчанию.int
: соответствует любому положительному числу, а также нулю.slug
: соответствует последовательности буквенных символов ASCII, цифр, дефиса и символа подчеркивания, например:building-your-1st-django-site
.uuid
: соответствует идентификатору UUID, например:075194d3-6885-417e-a8a8-6c931e272f00
.path
: соответствует любой строке, которая также может включать символ/
в отличие от спецификатораstr
.
Также отмечу, что количество и название параметров в шаблонах адресов URL соответствуют количеству и названиям параметров соответствующих функций, которые обрабатывают запросы по данным адресам.
Запустим отладочный сервер и выполним запрос по URL-адресу http://127.0.0.1:8000/user/Tom, который будет обработан функцией user()
.
В этом запросе мы передали значение для параметра 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
:
Рассмотрим ситуацию, когда мы не указываем значения для одного или для обоих параметров. В таком случае возникает ошибка.
Параметры маршрута являются частью шаблона пути. Если в строке запроса отсутствуют значения для этих параметров, то запрос не соответствует определённому маршруту. Из-за этого Django не сможет найти нужный маршрут для обработки запроса, и мы получаем ошибку 404 (ресурс не найден).
Но иногда такое поведение нежелательно. Мы можем задать значения по умолчанию для параметров маршрута на тот случай, если через строку запроса не передаются значения.
Изменим определение функции user()
в файле представлений views.py
, зададим для её параметров значения по умолчанию:
def user(request, name='Undefined', age=0):
return HttpResponse(f'<h2>Имя: {name} Возраст: {age}</h2>')
Если для параметра name
не будет передано значение, то он получит строку Undefined
в качестве значения. Для параметра age
значение по умолчанию задано равным 0
.
Но если данные параметры будут отсутствовать в запрошенном URL-адресе, то Django не сможет найти соответствующий ему маршрут. В данной ситуации необходимо определить дополнительные маршруты для функции 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),
]
Если мы запросим URL http://127.0.0.1:8000/user/Tom/38 , то получим страницу с текстом Имя: Tom, Возраст: 38
.
При запросе этого URL http://127.0.0.1:8000/user/Tom на странице будет текст Имя: Tom, Возраст: 0
, так как было использовано значение по умолчанию для параметра age
.
А для такого URL http://127.0.0.1:8000/user/ на странице будет такой текст Имя: Undefined, Возраст: 0
, так как были использованы значения по умолчанию для обоих параметров name
и age
.