> For the complete documentation index, see [llms.txt](https://ivanovskiy999.gitbook.io/django/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ivanovskiy999.gitbook.io/django/1.-vvedenie-v-django/1.4.-kontroller-funkcii-i-marshrutizaciya.md).

# 1.4. Контроллер-функции и маршрутизация

Контроллер Django — это код, запускаемый при обращении по интернет-адресу определенного формата и в ответ выводящий на экран определенную веб-страницу.

{% hint style="warning" %}
В документации по Django используется термин **View** (вид, или представление). Здесь будем использовать термин **Controller** (контроллер) \[см. раздел [О Django](/django/1.-vvedenie-v-django/o-django.md#chto-takoe-django)]
{% endhint %}

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

Для хранения кода контроллеров изначально предназначается модуль `views.py`, создаваемый в каждом пакете приложения.

## Создание контроллер-функции

Напишем контроллер-функцию, которая будет выводить строку `Hello world!`. Для этого откроем модуль `views.py` пакета приложения `firstapp`, заменим его содержимое следующим кодом:

```python
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello world!")
```

Здесь мы импортируем класс `HttpResponse` из стандартного пакета `django.http`.

Затем определяем функцию `index()`, которая в качестве единственного обязательного параметра получает экземпляр класса `HttpRequest`, хранящий различные сведения о полученном запросе: запрашиваемый интернет-адрес, данные, полученные от посетителя, служебную информацию от самого веб-обозревателя и пр. По традиции его называют `request`. В нашем случае мы его не используем.&#x20;

В теле функции мы создаем экземпляр класса `HttpResponse`. Он будет представлять ответ, отправляемый клиенту. Содержимое этого ответа — текстовое сообщение — указываем единственным параметром конструктора этого класса. Готовый экземпляр класса возвращаем в качестве результата.

## Создание маршрута

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

![](https://2798293355-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MY9bJBkBnScP4OsqUPJ%2F-MYFN4JzT42BKBD13V6k%2F-MYFRiRIBy5ivlKUOP4j%2Frunserver.png?alt=media\&token=8a8b3be8-7038-424d-9bce-9affef39a3a2)

Это произошло потому, что нигде не связали нашу написанную контроллер-функцию с интернет-адресом.

Откроем файл `urls.py`, находящийся в пакете конфигурации `firstsite`. Увидим в нём следующий код:

```python
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]
```

Здесь можно заметить список маршрутов `urlpatterns`. Каждый маршрут представляется в виде результата, возвращаемого функцией `path()` из `django.urls`. В качестве параметров она принимает строку с шаблонным путем и ссылку на контроллер.

В качестве второго параметра функции `path()` также можно передать список маршрутов уровня приложения. Этот вариант как раз демонстрируется в единственном маршруте нашего списка маршрутов.

Добавим в список новый маршрут, связывающий шаблонный путь `firstapp/` и контроллер-функцию `index()`. Для чего изменим код следующим образом:

```python
from django.contrib import admin
from django.urls import path
from firstapp.views import index

urlpatterns = [
    path('firstapp/', index),
    path('admin/', admin.site.urls),
]
```

Сохраним изменения, запустим наш проект и перейдем по адресу <http://127.0.0.1:8000/firstapp/>:

![](https://2798293355-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MY9bJBkBnScP4OsqUPJ%2F-MZ745AzNQoP29bdYLHT%2F-MZ74y0wKB36hoWTFo6m%2Fhelloworld.png?alt=media\&token=5e134d4c-238c-49e5-b051-1753194c3e76)

## Создание маршрутов с использованием функции `include()`:

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

Маршрутизатор Django при просмотре списка маршрутов не требует, чтобы путь, полученный из клиентского запроса (реальный), и шаблонный путь, записанный в очередном маршруте, совпадали полностью. Достаточно лишь того факта, что шаблонный путь совпадает с началом реального.

Как было сказано ранее, функция `path()` позволяет указать во втором параметре вместо ссылки на контроллер-функцию другой, *вложенный*, список маршрутов. В таком случае маршрутизатор, найдя совпадение, удалит из реального пути его начальную часть (префикс), совпавшую с шаблонным путем, и приступит к просмотру маршрутов из вложенного списка, используя для сравнения реальный путь уже без префикса.

Исходя из всего этого, мы можем создать иерархию списков маршрутов. В списке из пакета конфигурации *(списке маршрутов уровня проекта)* запишем маршруты, которые указывают на вложенные списки маршрутов, принадлежащие отдельным приложениям *(списки маршрутов уровня приложения)*. А в последних непосредственно запишем нужные контроллеры.

Начнем со списка маршрутов уровня приложения `firstapp`. Создадим в пакете этого приложения файл `urls.py` и напишем следующее:

```python
from django.urls import path
from .views import index

urlpatterns = [
    path('', index),
]
```

И, наконец, исправим код модуля `urls.py` из пакета конфигурации:

```python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('firstapp/', include('firstapp.urls')),
    path('admin/', admin.site.urls),
]
```

Вложенный список маршрутов, указываемый во втором параметре функции `path()`, должен представлять собой результат, возвращенный функцией `include()` из модуля `django.urls`. В качестве единственного параметра эта функция принимает строку с путем к модулю, где записан вложенный список маршрутов.

Как только наш сайт получит запрос с интернет-адресом [http://localhost:8000/firstapp/](http://localhost:8000/firstapp), маршрутизатор обнаружит, что присутствующий в нем путь совпадает с шаблонным путем `firstapp/`, записанным в `urls.py` из пакета конфигурации. Он удалит из реального пути префикс, соответствующий шаблонному пути, и получит новый путь — пустую строку. Этот путь совпадет с единственным маршрутом из вложенного списка, в результате чего запустится записанный в этом маршруте контроллер-функция `index()`, и на экране появится уже знакомое нам текстовое сообщение.
