Параметры представлений
Функции-представления могут принимать параметры, через которые могут передаваться различные данные. Подобные параметры передаются в адресе 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