# HTML и формы

DRF подходит для возврата как ответов в стиле API, так и обычных HTML-страниц. Кроме того, сериализаторы могут использоваться в качестве HTML-форм и отображаться в шаблонах.

## Рендеринг HTML

Для возврата HTML-ответов вам нужно использовать либо `TemplateHTMLRenderer`, либо `StaticHTMLRenderer`.

Класс `TemplateHTMLRenderer` ожидает, что ответ будет содержать словарь данных контекста, и создает HTML-страницу на основе шаблона, который должен быть указан либо в представлении, либо в ответе.

Класс `StaticHTMLRender` ожидает, что ответ будет содержать строку предварительно отрендеренного HTML-содержимого.

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

Вот пример представления, которое возвращает список экземпляров "Profile", отображенный в шаблоне HTML:

**views.py**:

```python
from my_project.example.models import Profile
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView


class ProfileList(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'profile_list.html'

    def get(self, request):
        queryset = Profile.objects.all()
        return Response({'profiles': queryset})
```

**profile\_list.html**:

```html
<html><body>
<h1>Profiles</h1>
<ul>
    <div data-gb-custom-block data-tag="for">

    <li>{{ profile.name }}</li>
    

</div>

</ul>
</body></html>
```

## Рендеринг форм

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

Следующее представление демонстрирует пример использования сериализатора в шаблоне для просмотра и обновления экземпляра модели:

**views.py**:

```python
from django.shortcuts import get_object_or_404
from my_project.example.models import Profile
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.views import APIView


class ProfileDetail(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'profile_detail.html'

    def get(self, request, pk):
        profile = get_object_or_404(Profile, pk=pk)
        serializer = ProfileSerializer(profile)
        return Response({'serializer': serializer, 'profile': profile})

    def post(self, request, pk):
        profile = get_object_or_404(Profile, pk=pk)
        serializer = ProfileSerializer(profile, data=request.data)
        if not serializer.is_valid():
            return Response({'serializer': serializer, 'profile': profile})
        serializer.save()
        return redirect('profile-list')
```

**profile\_detail.html**:

```html

<div data-gb-custom-block data-tag="load"></div>

<html><body>

<h1>Profile - {{ profile.name }}</h1>

<form action="

<div data-gb-custom-block data-tag="url" data-0='profile-detail'></div>" method="POST">
    <div data-gb-custom-block data-tag="csrf_token"></div>

    

<div data-gb-custom-block data-tag="render_form"></div>

    <input type="submit" value="Save">
</form>

</body></html>
```

### Использование пакетов шаблонов

Тег `render_form` принимает необязательный аргумент `template_pack`, который указывает, какой каталог шаблонов должен использоваться для рендеринга формы и полей формы.

DRF включает три встроенных пакета шаблонов, все они основаны на Bootstrap 3. Встроенные стили: `horizontal`, `vertical` и `inline`. По умолчанию используется стиль `horizontal`. Чтобы использовать любой из этих пакетов шаблонов, вам необходимо также включить CSS Bootstrap 3.

Следующий HTML будет ссылаться на версию CSS Bootstrap 3, размещенную в CDN:

```html
<head>
    …
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
```

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

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

```python
class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField(
        max_length=100,
        style={'placeholder': 'Email', 'autofocus': True}
    )
    password = serializers.CharField(
        max_length=100,
        style={'input_type': 'password', 'placeholder': 'Password'}
    )
    remember_me = serializers.BooleanField()
```

***

#### `rest_framework/vertical`.

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

*Это пакет шаблонов по умолчанию.*

```html

<div data-gb-custom-block data-tag="load"></div>

...

<form action="

<div data-gb-custom-block data-tag="url" data-0='login'></div>" method="post" novalidate>
    <div data-gb-custom-block data-tag="csrf_token"></div>

    

<div data-gb-custom-block data-tag="render_form" data-template_pack='rest_framework/vertical'></div>

    <button type="submit" class="btn btn-default">Sign in</button>
</form>
```

![Пример вертикальной формы](https://github.com/encode/django-rest-framework/raw/master/docs/img/vertical.png)

***

#### `rest_framework/horizontal`.

Представляет ярлыки и элементы управления рядом друг с другом, используя разделение колонок 2/10.

*Это стиль формы, используемый в Web-интерфейсе API и администраторских рендерах.*

```html

<div data-gb-custom-block data-tag="load"></div>

...

<form class="form-horizontal" action="

<div data-gb-custom-block data-tag="url" data-0='login'></div>" method="post" novalidate>
    <div data-gb-custom-block data-tag="csrf_token"></div>

    

<div data-gb-custom-block data-tag="render_form"></div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-default">Sign in</button>
        </div>
    </div>
</form>
```

![Пример горизонтальной формы](https://github.com/encode/django-rest-framework/raw/master/docs/img/horizontal.png)

***

#### `rest_framework/inline`.

Компактный стиль формы, который представляет все элементы управления в линию.

```html

<div data-gb-custom-block data-tag="load"></div>

...

<form class="form-inline" action="

<div data-gb-custom-block data-tag="url" data-0='login'></div>" method="post" novalidate>
    <div data-gb-custom-block data-tag="csrf_token"></div>

    

<div data-gb-custom-block data-tag="render_form" data-template_pack='rest_framework/inline'></div>
    <button type="submit" class="btn btn-default">Sign in</button>
</form>
```

![Пример инлайн-формы](https://github.com/encode/django-rest-framework/raw/master/docs/img/inline.png)

## Стили полей

Поля сериализатора могут иметь свой стиль рендеринга, настроенный с помощью именованного аргумента `style`. Этот аргумент представляет собой словарь опций, которые управляют используемым шаблоном и макетом.

Наиболее распространенным способом настройки стиля поля является использование именованного аргумента стиля `base_template`, чтобы выбрать, какой шаблон из пакета шаблонов следует использовать.

Например, чтобы отобразить `CharField` как HTML textarea, а не как HTML input по умолчанию, вы должны использовать что-то вроде этого:

```python
details = serializers.CharField(
    max_length=1000,
    style={'base_template': 'textarea.html'}
)
```

Если вы хотите, чтобы поле отображалось с использованием пользовательского шаблона, который *не является частью включенного пакета шаблонов*, вы можете использовать опцию стиля `template`, чтобы полностью указать имя шаблона:

```python
details = serializers.CharField(
    max_length=1000,
    style={'template': 'my-field-templates/custom-input.html'}
)
```

Шаблоны полей также могут использовать дополнительные свойства стиля, в зависимости от их типа. Например, шаблон `textarea.html` также принимает свойство `rows`, которое можно использовать для изменения размера элемента управления.

```python
details = serializers.CharField(
    max_length=1000,
    style={'base_template': 'textarea.html', 'rows': 10}
)
```

Полный список опций `base_template` и связанных с ними опций стиля приведен ниже.

| base\_template          | Правильные типы полей                                    | Дополнительные параметры стиля                   |
| ----------------------- | -------------------------------------------------------- | ------------------------------------------------ |
| input.html              | Любое строковое, числовое или поле даты/времени          | input\_type, placeholder, hide\_label, autofocus |
| textarea.html           | `CharField`                                              | rows, placeholder, hide\_label                   |
| select.html             | `ChoiceField` или типы реляционных полей                 | hide\_label                                      |
| radio.html              | `ChoiceField` или реляционные типы поля                  | inline, hide\_label                              |
| select\_multiple.html   | `MultipleChoiceField` или реляционные поля с `many=True` | hide\_label                                      |
| checkbox\_multiple.html | `MultipleChoiceField` или реляционные поля с `many=True` | inline, hide\_label                              |
| checkbox.html           | `BooleanField`                                           | hide\_label                                      |
| fieldset.html           | Вложенный сериализатор                                   | hide\_label                                      |
| list\_fieldset.html     | `ListField` или вложенный сериализатор с `many=True`     | hide\_label                                      |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ilyachch.gitbook.io/django-rest-framework-russian-documentation/stati/topics/html-and-forms.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
