diff options
Diffstat (limited to 'files/ru/learn/server-side/django/forms/index.html')
| -rw-r--r-- | files/ru/learn/server-side/django/forms/index.html | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/files/ru/learn/server-side/django/forms/index.html b/files/ru/learn/server-side/django/forms/index.html index 902e27932d..d43c505096 100644 --- a/files/ru/learn/server-side/django/forms/index.html +++ b/files/ru/learn/server-side/django/forms/index.html @@ -25,7 +25,7 @@ translation_of: Learn/Server-side/Django/Forms </tr> <tr> <th scope="row">Цель:</th> - <td>Научиться понимать, как создавать формы, чтобы получать информацию от пользователей и обновлять базу данных. Узнать, как обобщенные классы отображения форм могут значительно упростить процесс создания форм при работе с одной моделью.</td> + <td>Научиться понимать, как создавать формы, чтобы получать информацию от пользователей и обновлять базу данных. Узнать, как обобщённые классы отображения форм могут значительно упростить процесс создания форм при работе с одной моделью.</td> </tr> </tbody> </table> @@ -38,13 +38,13 @@ translation_of: Learn/Server-side/Django/Forms <p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> -<p>Работа с формами может быть достаточно сложной! Разработчикам надо описать форму на HTML, проверить ее валидность, а также, на стороне сервера, проверять введенные пользователем данные (а возможно и на стороне клиента), далее, в случае возникновения ошибок необходимо опять показать пользователю форму и, при этом, указать на то, что пошло не так, в случае же успеха проделать с данными необходимые операции и каким-то образом проинформировать об этом пользователя. Django, при работе с формами, берет большую часть, описанной выше работы, на себя. Он предоставляет фреймворк, который позволяет вам определять форму и ее поля программно, а затем использовать эти объекты и для генерации непосредственно кода HTML-формы, и для контроля за процессом валидации и других пользовательский взаимодействий с формой.</p> +<p>Работа с формами может быть достаточно сложной! Разработчикам надо описать форму на HTML, проверить её валидность, а также, на стороне сервера, проверять введённые пользователем данные (а возможно и на стороне клиента), далее, в случае возникновения ошибок необходимо опять показать пользователю форму и, при этом, указать на то, что пошло не так, в случае же успеха проделать с данными необходимые операции и каким-то образом проинформировать об этом пользователя. Django, при работе с формами, берет большую часть, описанной выше работы, на себя. Он предоставляет фреймворк, который позволяет вам определять форму и её поля программно, а затем использовать эти объекты и для генерации непосредственно кода HTML-формы, и для контроля за процессом валидации и других пользовательский взаимодействий с формой.</p> -<p>В данной части руководства мы покажем вам несколько способов создания и работы с формами и, в частности, как применение обобщенных классов работы с формой могут значительно уменьшить необходимый объем работы. Кроме того, мы расширим возможности нашего сайта <em>LocalLibrary,</em> путем добавления функционала для библиотекарей, который будет позволять им обновлять информацию - добавим страницы для создания, редактирования, удаления книг и авторов (воспроизведем и расширим стандартные возможности административной части сайта).</p> +<p>В данной части руководства мы покажем вам несколько способов создания и работы с формами и, в частности, как применение обобщённых классов работы с формой могут значительно уменьшить необходимый объем работы. Кроме того, мы расширим возможности нашего сайта <em>LocalLibrary,</em> путём добавления функционала для библиотекарей, который будет позволять им обновлять информацию - добавим страницы для создания, редактирования, удаления книг и авторов (воспроизведём и расширим стандартные возможности административной части сайта).</p> <h2 id="Формы_HTML">Формы HTML</h2> -<p>Начнем мы с краткого обзора <a href="/en-US/docs/Web/Guide/HTML/Forms">Форм HTML</a>. Рассмотрим простую форму HTML, имеющую поле для ввода имени некоторой "команды" ("team"), и, связанную с данным полем, текстовой меткой:</p> +<p>Начнём мы с краткого обзора <a href="/en-US/docs/Web/Guide/HTML/Forms">Форм HTML</a>. Рассмотрим простую форму HTML, имеющую поле для ввода имени некоторой "команды" ("team"), и, связанную с данным полем, текстовой меткой:</p> <p><img alt="Simple name field example in HTML form" src="https://mdn.mozillademos.org/files/14117/form_example_name_field.png" style="border-style: solid; border-width: 1px; display: block; height: 44px; margin: 0px auto; width: 399px;"></p> @@ -58,27 +58,27 @@ translation_of: Learn/Server-side/Django/Forms <p>Здесь у нас только одно поле для ввода имени команды, но форма <em>может</em> иметь любое количество элементов ввода и, связанных с ними, текстовых меток. Атрибут элемента <code>type</code> определяет какого типа виджет будет показан в данной строке. Атрибуты <code>name</code> и <code>id</code> используются для однозначной идентификации данного поля в JavaScript/CSS/HTML, в то время как <code>value</code> содержит значение для поля (когда оно показывается в первый раз). Текстовая метка добавляется при помощи тэга <code style="font-style: normal; font-weight: normal;">label</code> (смотрите "Enter name", в предыдущем фрагменте) и имеет атрибут <code style="font-style: normal; font-weight: normal;">for</code> со значением идентификатора <code style="font-style: normal; font-weight: normal;">id</code>, того поля, с которым данная текстовая метка связана.</p> -<p>Элемент <code>input</code> с <code>type="submit"</code> будет показана как кнопка (по умолчанию), нажав на которую, пользователь отправляет введенные им данные на сервер (в данном случае только значение поля с идентификатором <code>team_name</code>). Атрибуты формы определяют каким методом будут отправлены данные на сервер (атрибут <code>method</code>) и куда (атрибут <code>action</code>):</p> +<p>Элемент <code>input</code> с <code>type="submit"</code> будет показана как кнопка (по умолчанию), нажав на которую, пользователь отправляет введённые им данные на сервер (в данном случае только значение поля с идентификатором <code>team_name</code>). Атрибуты формы определяют каким методом будут отправлены данные на сервер (атрибут <code>method</code>) и куда (атрибут <code>action</code>):</p> <ul> <li><code>action</code>: Это ресурс/URL-адрес куда будут отправлены данные для обработки. Если значение не установлено (то есть, значением поля является пустая строка), тогда данные будут отправлены в отображение (функцию, или класс), которое сформировало текущую страницу.</li> <li><code>method</code>: HTTP-метод, используемый для отправки данных: <em>post</em>, или <em>get</em>. <ul> - <li>Метод <code>POST</code> должен всегда использоваться если отправка данных приведет к внесению изменений в базе данных на сервере. Применение данного метода должно повысить уровень защиты от CSRF.</li> + <li>Метод <code>POST</code> должен всегда использоваться если отправка данных приведёт к внесению изменений в базе данных на сервере. Применение данного метода должно повысить уровень защиты от CSRF.</li> <li>Метод <code>GET</code> должен применяться только для форм, действия с которыми не приводят к изменению базы данных (например для поисковых запросов). Кроме того, данный метод рекомендуется применять для создания внешних ссылок на ресурсы сайта.</li> </ul> </li> </ul> -<p>Ролью сервера в первую очередь является отрисовка начального состояния формы — либо содержащей пустые поля, либо с установленными начальными значениями. После того как пользователь нажмет на кнопку, сервер получит все данные формы, а затем должен провести их валидацию. В том случае, если форма содержит неверные данные, сервер должен снова отрисовать форму, показав при этом поля с правильными данными, а также сообщения, описывающие "что именно пошло не так". В тот момент, когда сервер получит запрос с "правильными" данными он должен выполнить все необходимые действия (например, сохранение данных, возврат результата поиска, загрузка файла и тому подобное), а затем, в случае необходимости, проинформировать пользователя.</p> +<p>Ролью сервера в первую очередь является отрисовка начального состояния формы — либо содержащей пустые поля, либо с установленными начальными значениями. После того как пользователь нажмёт на кнопку, сервер получит все данные формы, а затем должен провести их валидацию. В том случае, если форма содержит неверные данные, сервер должен снова отрисовать форму, показав при этом поля с правильными данными, а также сообщения, описывающие "что именно пошло не так". В тот момент, когда сервер получит запрос с "правильными" данными он должен выполнить все необходимые действия (например, сохранение данных, возврат результата поиска, загрузка файла и тому подобное), а затем, в случае необходимости, проинформировать пользователя.</p> -<p>Как вы видите, создание HTML-формы, валидация и возврат данных, переотрисовка введенных значений, при необходимости, а также выполнение желаемых действий с "правильными данными", в целом, может потребовать довольно больших усилий для того, чтобы все "заработало". Django делает этот процесс намного проще, беря на себя некоторые "тяжелые" и повторяющиеся участки кода!</p> +<p>Как вы видите, создание HTML-формы, валидация и возврат данных, переотрисовка введённых значений, при необходимости, а также выполнение желаемых действий с "правильными данными", в целом, может потребовать довольно больших усилий для того, чтобы все "заработало". Django делает этот процесс намного проще, беря на себя некоторые "тяжёлые" и повторяющиеся участки кода!</p> <h2 id="Процесс_управления_формой_в_Django_2"><a id="Процесс_управления_формой_в_Django" name="Процесс_управления_формой_в_Django">Процесс управления формой в Django</a></h2> -<p>Управление формами в Django использует те же самые техники, которые мы изучали в предыдущих частях руководства (при показе информации из наших моделей): отображение получает запрос, выполняет необходимые действия, включающие в себя чтение данных из моделей, генерацию и возврат страницы HTML (из шаблона, в который передается <em>контекст,</em> содержащий данные, которые и будут показаны). Что делает данный процесс более сложным, так это то, что серверной части надо дополнительно обработать данные, предоставленные пользователем и, в случае возникновения ошибок, снова перерисовать страницу.</p> +<p>Управление формами в Django использует те же самые техники, которые мы изучали в предыдущих частях руководства (при показе информации из наших моделей): отображение получает запрос, выполняет необходимые действия, включающие в себя чтение данных из моделей, генерацию и возврат страницы HTML (из шаблона, в который передаётся <em>контекст,</em> содержащий данные, которые и будут показаны). Что делает данный процесс более сложным, так это то, что серверной части надо дополнительно обработать данные, предоставленные пользователем и, в случае возникновения ошибок, снова перерисовать страницу.</p> -<p>Диаграмма, представленная ниже, демонстрирует процесс работы с формой в Django, начиная с запроса страницы, содержащей форму (выделено зеленым цветом).</p> +<p>Диаграмма, представленная ниже, демонстрирует процесс работы с формой в Django, начиная с запроса страницы, содержащей форму (выделено зелёным цветом).</p> <p><img alt="Updated form handling process doc." src="https://mdn.mozillademos.org/files/14205/Form%20Handling%20-%20Standard.png" style="display: block; height: 569px; margin: 0px auto; width: 800px;"></p> @@ -87,27 +87,27 @@ translation_of: Learn/Server-side/Django/Forms <ol> <li>Показ формы по умолчанию при первом запросе со стороны пользователя. <ul> - <li>Форма может содержать пустые поля (например, если вы создаете новую запись в базе данных), или они (поля) могут иметь начальные значения (например, если вы изменяете запись, или хотите заполнить ее каким-либо начальным значением).</li> - <li>Форма в данный момент является <em>несвязанной</em>, потому что она не ассоциируется с какими-либо введенными пользователем данными (хотя и может иметь начальные значения).</li> + <li>Форма может содержать пустые поля (например, если вы создаёте новую запись в базе данных), или они (поля) могут иметь начальные значения (например, если вы изменяете запись, или хотите заполнить её каким-либо начальным значением).</li> + <li>Форма в данный момент является <em>несвязанной</em>, потому что она не ассоциируется с какими-либо введёнными пользователем данными (хотя и может иметь начальные значения).</li> </ul> </li> <li>Получение данных из формы (из HTML-формы) со стороны клиента и связывание их с формой (классом формы) на стороне сервера. <ul> - <li>Связывание данных с формой означает, что данные, введенные пользователем, а также возможные ошибки, при переотрисовке в дальнейшем, будут относиться именно к данной форме, а не к какой-либо еще.</li> + <li>Связывание данных с формой означает, что данные, введённые пользователем, а также возможные ошибки, при переотрисовке в дальнейшем, будут относиться именно к данной форме, а не к какой-либо еще.</li> </ul> </li> <li>Очистка и валидация данных. <ul> <li>Очистка данных - это их проверка на наличие возможных значений, или вставок в поля ввода (то есть очистка - это удаление неправильных символов, которые потенциально могут использоваться для отправки вредоносного содержимого на сервер), с последующей конвертацией очищенных данных в подходящие типы данных Python.</li> - <li>Валидация проверяет, значения полей (например, правильность введенных дат, их диапазон и так далее)</li> + <li>Валидация проверяет, значения полей (например, правильность введённых дат, их диапазон и так далее)</li> </ul> </li> - <li>Если какие-либо данные являются неверными, то выполнение перерисовки формы, но на этот раз, с уже введенными пользователем данными и сообщениями об ошибках, описывающих возникшие проблемы.</li> + <li>Если какие-либо данные являются неверными, то выполнение перерисовки формы, но на этот раз, с уже введёнными пользователем данными и сообщениями об ошибках, описывающих возникшие проблемы.</li> <li>Если все данные верны, то исполнение необходимых действий (например, сохранение данных, отправка писем, возврат результата поиска, загрузка файла и так далее)</li> <li>Когда все действия были успешно завершены, то перенаправление пользователя на другую страницу.</li> </ol> -<p>Django предоставляет несколько инструментов и приемов, которые помогают вам во время выполнения задач, описанных выше. Наиболее фундаментальным из них является класс <code>Form</code>, который упрощает генерацию HTML-формы и очистку/валидацию ее данных. В следующем разделе мы опишем процесс работы с формами при помощи практического примера по созданию страницы, которая позволит библиотекарям обновлять информацию о книгах.</p> +<p>Django предоставляет несколько инструментов и приёмов, которые помогают вам во время выполнения задач, описанных выше. Наиболее фундаментальным из них является класс <code>Form</code>, который упрощает генерацию HTML-формы и очистку/валидацию её данных. В следующем разделе мы опишем процесс работы с формами при помощи практического примера по созданию страницы, которая позволит библиотекарям обновлять информацию о книгах.</p> <div class="note"> <p><strong>Примечание:</strong> Понимание того, как используется класс <code>Form</code> поможет вам когда мы будем рассматривать классы фреймворка Django, для работы с формами более "высокого уровня".</p> @@ -115,13 +115,13 @@ translation_of: Learn/Server-side/Django/Forms <h2 id="HTML-форма_обновления_книги._Класс_Form_и_функция_отображения">HTML-форма обновления книги. Класс Form и функция отображения</h2> -<p>Данная глава будет посвящена процессу создания страницы, которая позволит библиотекарям обновлять информацию о книгах (в частности, вводить дату возврата книги). Для того, чтобы сделать это мы создадим форму, которая позволит пользователям вводить значение дат. Мы проинициализируем поле датой, равной 3 неделям, начиная с текущего дня, и, для того, чтобы библиотекарь не имел возможность ввести "неправильную" дату, мы добавим валидацию введенных значений, которая будет проверять, чтобы введенная дата не относилась к прошлому, или к слишком далекому будущему. Когда будет получена "правильная" дата мы запишем ее значение в поле <code>BookInstance.due_back</code>.</p> +<p>Данная глава будет посвящена процессу создания страницы, которая позволит библиотекарям обновлять информацию о книгах (в частности, вводить дату возврата книги). Для того, чтобы сделать это мы создадим форму, которая позволит пользователям вводить значение дат. Мы проинициализируем поле датой, равной 3 неделям, начиная с текущего дня, и, для того, чтобы библиотекарь не имел возможность ввести "неправильную" дату, мы добавим валидацию введённых значений, которая будет проверять, чтобы введённая дата не относилась к прошлому, или к слишком далёкому будущему. Когда будет получена "правильная" дата мы запишем её значение в поле <code>BookInstance.due_back</code>.</p> <p>Данный пример будет использовать отображение на основе функции, а также продемонстрирует работу с классом <code>Form</code>. Следующие разделы покажут изменения, которые вам надо сделать, чтобы продемонстрировать работу форм в проекте <em>LocalLibrary</em>.</p> <h3 id="Класс_Form">Класс Form</h3> -<p>Класс <code>Form</code> является сердцем системы Django при работе с формами. Он определяет поля формы, их расположение, показ виджетов, текстовых меток, начальных значений, валидацию значений и сообщения об ошибках для "неправильных" полей (если таковые имеются). Данный класс, кроме того, предоставляет методы для отрисовки самого себя в шаблоне при помощи предопределенных форматов (таблицы, списки и так далее), или для получения значения любого элемента (позволяя выполнять более точную отрисовку).</p> +<p>Класс <code>Form</code> является сердцем системы Django при работе с формами. Он определяет поля формы, их расположение, показ виджетов, текстовых меток, начальных значений, валидацию значений и сообщения об ошибках для "неправильных" полей (если таковые имеются). Данный класс, кроме того, предоставляет методы для отрисовки самого себя в шаблоне при помощи предопределённых форматов (таблицы, списки и так далее), или для получения значения любого элемента (позволяя выполнять более точную отрисовку).</p> <h4 id="Объявление_класса_формы_Form">Объявление класса формы Form</h4> @@ -137,7 +137,7 @@ class RenewBookForm(forms.Form): <h4 id="Поля_формы">Поля формы</h4> -<p>В нашем случае мы имеем одно поле типа <code><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datefield">DateField</a></code>, которое служит для ввода обновленной даты возврата книги, которое будет отрендерено в HTML с пустым значением и текстовой меткой "<em>Renewal date:</em>", а также текстовым описанием: "<em>Enter a date between now and 4 weeks (default 3 weeks).</em>" Так как никаких дополнительных опций мы не определяем, то поле будет "получать" даты в следующем формате <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#django.forms.DateField.input_formats">input_formats</a>: YYYY-MM-DD (2016-11-06), MM/DD/YYYY (02/26/2016), MM/DD/YY (10/25/16), а для отрисовки по умолчанию, будет использовать <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#widget">виджет</a>: <a href="https://docs.djangoproject.com/en/1.10/ref/forms/widgets/#django.forms.DateInput">DateInput</a>.</p> +<p>В нашем случае мы имеем одно поле типа <code><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datefield">DateField</a></code>, которое служит для ввода обновлённой даты возврата книги, которое будет отрендерено в HTML с пустым значением и текстовой меткой "<em>Renewal date:</em>", а также текстовым описанием: "<em>Enter a date between now and 4 weeks (default 3 weeks).</em>" Так как никаких дополнительных опций мы не определяем, то поле будет "получать" даты в следующем формате <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#django.forms.DateField.input_formats">input_formats</a>: YYYY-MM-DD (2016-11-06), MM/DD/YYYY (02/26/2016), MM/DD/YY (10/25/16), а для отрисовки по умолчанию, будет использовать <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#widget">виджет</a>: <a href="https://docs.djangoproject.com/en/1.10/ref/forms/widgets/#django.forms.DateInput">DateInput</a>.</p> <p>Существует множество других типов полей для класса формы, которые по своему функционалу подобны соответствующим им эквивалентам типов полей для классов моделей: <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#booleanfield"><code>BooleanField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#charfield"><code>CharField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#choicefield"><code>ChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#typedchoicefield"><code>TypedChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datefield"><code>DateField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datetimefield"><code>DateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#decimalfield"><code>DecimalField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#durationfield"><code>DurationField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#emailfield"><code>EmailField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#filefield"><code>FileField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#filepathfield"><code>FilePathField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#floatfield"><code>FloatField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#imagefield"><code>ImageField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#integerfield"><code>IntegerField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#genericipaddressfield"><code>GenericIPAddressField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#multiplechoicefield"><code>MultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#typedmultiplechoicefield"><code>TypedMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#nullbooleanfield"><code>NullBooleanField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#regexfield"><code>RegexField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#slugfield"><code>SlugField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#timefield"><code>TimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#urlfield"><code>URLField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#uuidfield"><code>UUIDField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#combofield"><code>ComboField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#multivaluefield"><code>MultiValueField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#splitdatetimefield"><code>SplitDateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#modelmultiplechoicefield"><code>ModelMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#modelchoicefield"><code>ModelChoiceField</code></a>.</p> @@ -145,20 +145,20 @@ class RenewBookForm(forms.Form): <ul> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#required">required</a>: Если <code>True</code>, то данное поле не может быть пустым, или иметь значение<code>None</code>. Данное значение установлено по умолчанию.</li> - <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a>: Текстовая метка, используемая для рендеринга поля в HTML-код. Если <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a> не определена, то Django попытается создать ее значение при помощи имени поля, переводя первый символ в верхний регистр, а также заменяя символы подчеркивания пробелами (например, для переменной с именем renewal_date, будет создан следующий текст метки: <em>Renewal date</em>).</li> + <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a>: Текстовая метка, используемая для рендеринга поля в HTML-код. Если <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a> не определена, то Django попытается создать её значение при помощи имени поля, переводя первый символ в верхний регистр, а также заменяя символы подчёркивания пробелами (например, для переменной с именем renewal_date, будет создан следующий текст метки: <em>Renewal date</em>).</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label-suffix">label_suffix</a>: По умолчанию показывает двоеточие после текста метки (например, Renewal date<strong>:</strong>). Данный параметр позволяет вам указать любой суффикс по вашему желанию.</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#initial">initial</a>: Начальное значение для поля при показе формы.</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#widget">widget</a>: Применяемый виджет для поля.</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#help-text">help_text</a> (как показано в примере выше): Дополнительный текст, который может быть показан на форме, для описания того, как использовать поле.</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#error-messages">error_messages</a>: Список сообщений об ошибках для данного поля. Вы можете переопределить его своими сообщениями, при необходимости.</li> - <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#validators">validators</a>: Список функций, которые будут вызваны для валидации, введенного в поле значения.</li> + <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#validators">validators</a>: Список функций, которые будут вызваны для валидации, введённого в поле значения.</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#localize">localize</a>: Позволяет осуществить локализацию данных поля формы (например, формат ввода числовых значений, или дат).</li> <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#disabled">disabled</a>: Если установлено в <code>True</code>, то поле показывается, но его значение изменить нельзя. По умолчанию равно <code>False</code>.</li> </ul> <h4 id="Валидация">Валидация</h4> -<p>Django предоставляет несколько мест где вы можете осуществить валидацию ваших данных. Простейшим способом проверки значения одиночного поля является переопределение метода<code>clean_<strong><fieldname></strong>()</code> (здесь, <code><strong><fieldname></strong></code> это имя поля, которое вы хотите проверить). Например, мы хотим проверить, что введенное значение <code>renewal_date</code> находится между текущей датой и 4 неделями в будущем. Для этого мы создаем метод <code>clean_<strong>renewal_date</strong>()</code>, как показано ниже:</p> +<p>Django предоставляет несколько мест где вы можете осуществить валидацию ваших данных. Простейшим способом проверки значения одиночного поля является переопределение метода<code>clean_<strong><fieldname></strong>()</code> (здесь, <code><strong><fieldname></strong></code> это имя поля, которое вы хотите проверить). Например, мы хотим проверить, что введённое значение <code>renewal_date</code> находится между текущей датой и 4 неделями в будущем. Для этого мы создаём метод <code>clean_<strong>renewal_date</strong>()</code>, как показано ниже:</p> <pre class="brush: python notranslate">from django import forms @@ -183,7 +183,7 @@ class RenewBookForm(forms.Form): # Помните, что всегда надо возвращать "очищенные" данные. return data</strong></pre> -<p>Необходимо отметить два важных момента. Первый это то, что мы получаем наши данные при помощи словаря <code>self.cleaned_data['renewal_date']</code>, а затем в конце возвращаем полученное значение, для проведения необходимых проверок. Данный шаг позволяет нам, при помощи валидаторов, получить "очищенные", проверенные, а затем, приведенные к стандартным типам, данные (в нашем случае к типу Python <code>datetime.datetime</code>).</p> +<p>Необходимо отметить два важных момента. Первый это то, что мы получаем наши данные при помощи словаря <code>self.cleaned_data['renewal_date']</code>, а затем в конце возвращаем полученное значение, для проведения необходимых проверок. Данный шаг позволяет нам, при помощи валидаторов, получить "очищенные", проверенные, а затем, приведённые к стандартным типам, данные (в нашем случае к типу Python <code>datetime.datetime</code>).</p> <p>Второй момент касается того случая, когда наше значение "выпадает за рамки" и мы "выкидываем" исключение <code>ValidationError</code>, в котором указываем текст, который мы хотим показать на форме, для случая когда были введены неправильные данные. Пример, показанный выше, оборачивает данный текст при помощи <a href="https://docs.djangoproject.com/en/1.10/topics/i18n/translation/">функции перевода Django</a> <code>ugettext_lazy()</code> (импортируемую через <code>_()</code>), которая может вам пригодиться, если вы планируете перевести ваш сайт в будущем.</p> @@ -208,14 +208,14 @@ class RenewBookForm(forms.Form): <p>Данная конфигурация перенаправит запросы с адресов формата <strong>/catalog/book/<em><bookinstance id></em>/renew/</strong> в функции с именем <code>renew_book_librarian()</code> в <strong>views.py</strong>, туда же передаст идентификатор id записи <code>BookInstance</code> в качестве параметра с именем <code>pk</code>. Шаблон соответствует только если <strong>pk </strong>это правильно отформатированный <strong>uiid.</strong></p> <div class="note"> -<p><strong>Примечание</strong>: Вместо имени "pk" мы можем использовать любое другое, по нашему желанию, потому что мы имеем полный контроль над функцией отображения (которого у нас нет в случае использования встроенного обобщенного класса отображения, который ожидает параметр с определенным именем). Тем не менее имя <code>pk</code> является понятным сокращением от "primary key", поэтому мы его тут и используем!</p> +<p><strong>Примечание</strong>: Вместо имени "pk" мы можем использовать любое другое, по нашему желанию, потому что мы имеем полный контроль над функцией отображения (которого у нас нет в случае использования встроенного обобщённого класса отображения, который ожидает параметр с определённым именем). Тем не менее имя <code>pk</code> является понятным сокращением от "primary key", поэтому мы его тут и используем!</p> </div> <h3 id="Отображение">Отображение</h3> -<p>Как было отмечено в разделе <a href="#Процесс_управления_формой_в_Django">Процесс управление формой в Django</a>, отображение должно отрендерить форму по умолчанию, когда она вызывается в первый раз и, затем, перерендерить ее, в том случае, если возникли какие-либо ошибки при работе с ее полями. В случае же успеха, после обработки "правильных" данных отображение перенаправляет пользователя на новую (другую) страницу. Для того чтобы выполнить все эти действия, отображение должно знать вызвано ли оно в первый раз для отрисовки формы по умолчанию, а если это не так, то провести валидацию полученных данных.</p> +<p>Как было отмечено в разделе <a href="#Процесс_управления_формой_в_Django">Процесс управление формой в Django</a>, отображение должно отрендерить форму по умолчанию, когда она вызывается в первый раз и, затем, перерендерить её, в том случае, если возникли какие-либо ошибки при работе с её полями. В случае же успеха, после обработки "правильных" данных отображение перенаправляет пользователя на новую (другую) страницу. Для того чтобы выполнить все эти действия, отображение должно знать вызвано ли оно в первый раз для отрисовки формы по умолчанию, а если это не так, то провести валидацию полученных данных.</p> -<p>Для форм, которые используют <code>POST</code>-запрос при отправке информации на сервер, наиболее общей схемой проверки данного факта является следующая строка кода <code>if request.method == 'POST':</code>. <code>GET</code>-запросу, а также первому запросу формы, в таком случае соответствует блок <code>else</code>. Если вы хотите отправлять свои данные в виде <code>GET</code>-запроса, то в таком случае приемом проверки того факта, что данный запрос первый (или последующий), является получение значения какого-либо поля формы (например, если значение скрытого поля формы пустое, то данный вызов является первым).</p> +<p>Для форм, которые используют <code>POST</code>-запрос при отправке информации на сервер, наиболее общей схемой проверки данного факта является следующая строка кода <code>if request.method == 'POST':</code>. <code>GET</code>-запросу, а также первому запросу формы, в таком случае соответствует блок <code>else</code>. Если вы хотите отправлять свои данные в виде <code>GET</code>-запроса, то в таком случае приёмом проверки того факта, что данный запрос первый (или последующий), является получение значения какого-либо поля формы (например, если значение скрытого поля формы пустое, то данный вызов является первым).</p> <p>Процесс обновления книги приводит к изменению информации в базе данных, таким образом, в соответствии с нашими соглашениями, в таком случае мы должны применять запрос типа <code>POST</code>. Фрагмент кода, представленный ниже, показывает (наиболее общую) схему работы для таких запросов. </p> @@ -232,7 +232,7 @@ def renew_book_librarian(request, pk): # Если данный запрос типа POST, тогда <strong> if request.method == 'POST':</strong> - # Создаем экземпляр формы и заполняем данными из запроса (связывание, binding): + # Создаём экземпляр формы и заполняем данными из запроса (связывание, binding): form = RenewBookForm(request.POST) # Проверка валидности данных формы: @@ -245,7 +245,7 @@ def renew_book_librarian(request, pk): # Переход по адресу 'all-borrowed': return HttpResponseRedirect(reverse('all-borrowed') ) - # Если это GET (или какой-либо еще), создать форму по умолчанию. + # Если это GET (или какой-либо ещё), создать форму по умолчанию. <strong> else:</strong> proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3) form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,}) @@ -255,33 +255,33 @@ def renew_book_librarian(request, pk): <p>В первую очередь мы импортируем наш класс формы (<code>RenewBookForm</code>), а также другие необходимые объекты и методы:</p> <ul> - <li><code><a href="https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#get-object-or-404">get_object_or_404()</a></code>: Возвращает определенный объект из модели в зависимости от значения его первичного ключа, или выбрасывает исключение <code>Http404</code>, если данной записи не существует. </li> + <li><code><a href="https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#get-object-or-404">get_object_or_404()</a></code>: Возвращает определённый объект из модели в зависимости от значения его первичного ключа, или выбрасывает исключение <code>Http404</code>, если данной записи не существует. </li> <li><code><a href="https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.HttpResponseRedirect">HttpResponseRedirect</a></code>: Данный класс перенаправляет на другой адрес (HTTP код статуса 302). </li> <li><code><a href="https://docs.djangoproject.com/en/1.10/ref/urlresolvers/#django.urls.reverse">reverse()</a></code>: Данная функция генерирует URL-адрес при помощи соответствующего имени URL конфигурации/преобразования и дополнительных аргументов. Это эквивалент Python тэгу <code>url</code>, которые мы использовали в наших шаблонах.</li> <li><code><a href="https://docs.python.org/3/library/datetime.html">datetime</a></code>: Библиотека Python для работы с датами и временим. </li> </ul> -<p>В отображении аргумент <code>pk</code> мы используем в функции<code>get_object_or_404()</code> для получения текущего объекта типа <code>BookInstance</code> (если его не существует, то функция, а следом и наше отображение прервут свое выполнение, а на странице пользователя отобразится сообщение об ошибке: "объект не найден"). Если запрос вызова отображения <em>не является</em> <code>POST</code>-запросом, то мы переходим к условному блоку <code>else</code>, в котором мы создаем форму по умолчанию и передаем ей начальное значения<code>initial</code> для поля <code>renewal_date</code> (выделено жирным ниже, - 3 недели, начиная с текущей даты). </p> +<p>В отображении аргумент <code>pk</code> мы используем в функции<code>get_object_or_404()</code> для получения текущего объекта типа <code>BookInstance</code> (если его не существует, то функция, а следом и наше отображение прервут своё выполнение, а на странице пользователя отобразится сообщение об ошибке: "объект не найден"). Если запрос вызова отображения <em>не является</em> <code>POST</code>-запросом, то мы переходим к условному блоку <code>else</code>, в котором мы создаём форму по умолчанию и передаём ей начальное значения<code>initial</code> для поля <code>renewal_date</code> (выделено жирным ниже, - 3 недели, начиная с текущей даты). </p> <pre class="brush: python notranslate"> book_inst = get_object_or_404(BookInstance, pk=pk) - # Если это GET (или другой метод), тогда создаем форму по умолчанию + # Если это GET (или другой метод), тогда создаём форму по умолчанию <strong>else:</strong> proposed_renewal_date = datetime.date.today() + datetime.timedelta(<strong>weeks=3</strong>) <strong>form = RenewBookForm(initial={'</strong>renewal_date<strong>': </strong>proposed_renewal_date<strong>,})</strong> return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})</pre> -<p>После создания формы мы вызываем функцию <code>render()</code>, чтобы создать HTML страницу; передаем ей в качестве параметров шаблон и контекст, который содержит объект формы. Кроме того, контекст содержит объект типа <code>BookInstance</code>, который мы будем использовать в шаблоне, для получения информации об обновляемой книге.</p> +<p>После создания формы мы вызываем функцию <code>render()</code>, чтобы создать HTML страницу; передаём ей в качестве параметров шаблон и контекст, который содержит объект формы. Кроме того, контекст содержит объект типа <code>BookInstance</code>, который мы будем использовать в шаблоне, для получения информации об обновляемой книге.</p> -<p>Если все таки у нас <code>POST</code>-запрос, тогда мы создаем объект с именем <code>form</code> и заполняем его данными, полученными из запроса. Данный процесс называется связыванием (или, биндингом, от англ. "binding") и позволяет нам провести валидацию данных. Далее осуществляется валидация формы, при этом проверяются все поля формы — для этого используются как код обобщенного класса, так и пользовательских функций, в частности нашей функции проверки введенных дат <code>clean_renewal_date()</code>. </p> +<p>Если все таки у нас <code>POST</code>-запрос, тогда мы создаём объект с именем <code>form</code> и заполняем его данными, полученными из запроса. Данный процесс называется связыванием (или, биндингом, от англ. "binding") и позволяет нам провести валидацию данных. Далее осуществляется валидация формы, при этом проверяются все поля формы — для этого используются как код обобщённого класса, так и пользовательских функций, в частности нашей функции проверки введённых дат <code>clean_renewal_date()</code>. </p> <pre class="brush: python notranslate"> book_inst = get_object_or_404(BookInstance, pk=pk) # Если данный запрос типа POST, тогда if request.method == 'POST': - # Создаем экземпляр формы и заполняем данными из запроса (связывание, binding): + # Создаём экземпляр формы и заполняем данными из запроса (связывание, binding): <strong> form = RenewBookForm(request.POST)</strong> # Проверка валидности формы: @@ -305,7 +305,7 @@ def renew_book_librarian(request, pk): <p>Последним шагом в части обработки формы представления является перенаправление на другую страницу, обычно страницу «Успех». В нашем случае мы используем объект класса <code>HttpResponseRedirect</code> и функцию <code>reverse()</code> для перехода к отображению с именем <code>'all-borrowed'</code> (это было домашним заданием в <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Руководство часть 8: Аутентификация и разграничение доступа</a>). Если вы не создали данную страницу, то просто укажите переход на домашнюю страницу сайта по адресу '/').</p> -<p>Все это необходимо для управления формой как таковой, но нам нужно как-то ограничить доступ к отображению (открыть доступ только библиотекарям). Мы могли бы создать новое разрешение (permission) в классе <code>BookInstance</code> ("<code>can_renew</code>"), но мы пойдем простым путем и воспользуемся функцией-декоратором <code>@permission_required</code> вместе с нашим существующим разрешением<code>can_mark_returned</code>.</p> +<p>Все это необходимо для управления формой как таковой, но нам нужно как-то ограничить доступ к отображению (открыть доступ только библиотекарям). Мы могли бы создать новое разрешение (permission) в классе <code>BookInstance</code> ("<code>can_renew</code>"), но мы пойдём простым путём и воспользуемся функцией-декоратором <code>@permission_required</code> вместе с нашим существующим разрешением<code>can_mark_returned</code>.</p> <p>Окончательный вид отображения показан ниже. Пожалуйста, скопируйте данный текст в нижнюю часть файла <strong>locallibrary/catalog/views.py</strong>.</p> @@ -369,12 +369,12 @@ def renew_book_librarian(request, pk): {% endblock %}</pre> -<p>Большая его часть вам знакома из предыдущих частей руководства. Мы расширяем базовый шаблон, а затем замещаем блок содержимого <code>content</code>. У нас имеется возможность ссылаться на переменную <code>\{{bookinst}}</code> (и ее поля) поскольку мы передали ее в объект контекста при вызове функции <code>render()</code>. Здесь мы используем данный объект для вывода заголовка книги, дат ее получения и возврата.</p> +<p>Большая его часть вам знакома из предыдущих частей руководства. Мы расширяем базовый шаблон, а затем замещаем блок содержимого <code>content</code>. У нас имеется возможность ссылаться на переменную <code>\{{bookinst}}</code> (и её поля) поскольку мы передали её в объект контекста при вызове функции <code>render()</code>. Здесь мы используем данный объект для вывода заголовка книги, дат её получения и возврата.</p> -<p>Код формы относительно прост. В первую очередь мы объявляем тэг<code>form</code>, затем определяем куда будут отправлены данные (<code>action</code>) и каким способом (<code>method</code>, в данном случае "HTTP POST") — если обратитесь к обзору раздела <a href="#HTML_forms">Формы HTML</a> в верхней части данной страницы, то найдете там замещение, что пустое значение атрибута <code>action</code>, означает, что данные из формы будут переданы обратно по текущему URL-адресу данной страницы (чего мы и хотим!). Внутри тэга формы мы объявляем кнопку <code>submit</code> при помощи которой мы можем отправить наши данные. Блок <code>{% csrf_token %}</code>, добавленный первой строкой внутри блока формы, является частью фреймворка Django и служит для борьбы с CSRF.</p> +<p>Код формы относительно прост. В первую очередь мы объявляем тэг<code>form</code>, затем определяем куда будут отправлены данные (<code>action</code>) и каким способом (<code>method</code>, в данном случае "HTTP POST") — если обратитесь к обзору раздела <a href="#HTML_forms">Формы HTML</a> в верхней части данной страницы, то найдёте там замещение, что пустое значение атрибута <code>action</code>, означает, что данные из формы будут переданы обратно по текущему URL-адресу данной страницы (чего мы и хотим!). Внутри тэга формы мы объявляем кнопку <code>submit</code> при помощи которой мы можем отправить наши данные. Блок <code>{% csrf_token %}</code>, добавленный первой строкой внутри блока формы, является частью фреймворка Django и служит для борьбы с CSRF.</p> <div class="note"> -<p><strong>Примечание:</strong> Добавляйте <code>{% csrf_token %}</code> в каждый шаблон Django, в котором вы создаете форму для отправки данных методом <code>POST</code>. Это поможет уменьшить вероятность взлома вашего сайта злоумышленниками.</p> +<p><strong>Примечание:</strong> Добавляйте <code>{% csrf_token %}</code> в каждый шаблон Django, в котором вы создаёте форму для отправки данных методом <code>POST</code>. Это поможет уменьшить вероятность взлома вашего сайта злоумышленниками.</p> </div> <p>Все что осталось, это указать переменную <code>\{{form}}</code>, которую мы передали в шаблон в словаре контекста. Возможно это вас не удивит, но таким образом мы предоставим возможность форме отрендерить свои поля с их метками, виджетами и дополнительными текстами, и в результате мы получим следующее:</p> @@ -390,7 +390,7 @@ def renew_book_librarian(request, pk): </pre> <div class="note"> -<p><strong>Примечание:</strong> Возможно это не очевидно, поскольку наша форма содержит только одно поле, но по умолчанию каждое поле формы помещается в ее собственную строку таблицы (поэтому переменная <code>\{{form}}</code> находится внутри тэга <code>table </code>. Тот же результат можно получить, если воспользоваться следующим вызовом <code>\{{ form.as_table }}</code>.</p> +<p><strong>Примечание:</strong> Возможно это не очевидно, поскольку наша форма содержит только одно поле, но по умолчанию каждое поле формы помещается в её собственную строку таблицы (поэтому переменная <code>\{{form}}</code> находится внутри тэга <code>table </code>. Тот же результат можно получить, если воспользоваться следующим вызовом <code>\{{ form.as_table }}</code>.</p> </div> <p>Если вы ввели неправильную дату, то на странице вы должны получить список сообщений об ошибках (показано жирным ниже).</p> @@ -411,7 +411,7 @@ def renew_book_librarian(request, pk): <p>В простом случае применения <code>\{{form}}</code> как показано выше, каждое поле рендерится в виде отдельной строки таблицы. Кроме того, вы можете отрендерить каждое поле как список элементов (<code>\{{form.as_ul}}</code> ), или как параграф (<code>\{{form.as_p}}</code>).</p> -<p>Что еще больше вдохновляет, так это то, что вы можете полностью контролировать процесс рендеринга любой части формы, используя для этого дот-нотацию (точку). Например, мы можем получить доступ к следующим полям поля формы <code>renewal_date</code>:</p> +<p>Что ещё больше вдохновляет, так это то, что вы можете полностью контролировать процесс рендеринга любой части формы, используя для этого дот-нотацию (точку). Например, мы можем получить доступ к следующим полям поля формы <code>renewal_date</code>:</p> <ul> <li><code>\{{form.renewal_date}}:</code> само поле.</li> @@ -425,7 +425,7 @@ def renew_book_librarian(request, pk): <h3 id="Тестирование_страницы">Тестирование страницы</h3> -<p>Если вы выполнили задание в <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django руководство часть 8: Аутентификация и разрешение доступа</a>, то у вас должна быть страница со списком всех книг в наличии библиотеки и данный список (страница) должен быть доступен только ее сотрудникам. На данной странице в каждом пункте (для каждой книги) мы можем добавить ссылку на нашу новую страницу обновления книги.</p> +<p>Если вы выполнили задание в <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django руководство часть 8: Аутентификация и разрешение доступа</a>, то у вас должна быть страница со списком всех книг в наличии библиотеки и данный список (страница) должен быть доступен только её сотрудникам. На данной странице в каждом пункте (для каждой книги) мы можем добавить ссылку на нашу новую страницу обновления книги.</p> <pre class="brush: html notranslate">{% if perms.catalog.can_mark_returned %}- <a href="{% url 'renew-book-librarian' bookinst.id %}">Renew</a> {% endif %}</pre> @@ -508,15 +508,15 @@ class RenewBookModelForm(ModelForm): <p>Теперь класс <code>RenewBookModelForm</code> является функциональным эквивалентом нашему предыдущему классу <code>RenewBookForm</code>. Вы можете импортировать и использовать его в тех же местах, где и <code>RenewBookForm</code>.</p> -<h2 id="Обобщенные_классы_отображения_для_редактирования">Обобщенные классы отображения для редактирования</h2> +<h2 id="Обобщённые_классы_отображения_для_редактирования">Обобщённые классы отображения для редактирования</h2> -<p>Алгоритм управления формой, который мы использовали в нашей функции отображения, является примером достаточно общего подхода к работе с формой. Django старается абстрагировать и упростить большую часть данной работы, путем широкого применения <a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/">обобщенных классов отображений</a>, которые служат для создания, редактирования и удаления отображений на основе моделей. Они не только управляют поведением отображения, но, кроме того, они из вашей модели автоматически создают класс формы (<code>ModelForm</code>).</p> +<p>Алгоритм управления формой, который мы использовали в нашей функции отображения, является примером достаточно общего подхода к работе с формой. Django старается абстрагировать и упростить большую часть данной работы, путём широкого применения <a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/">обобщённых классов отображений</a>, которые служат для создания, редактирования и удаления отображений на основе моделей. Они не только управляют поведением отображения, но, кроме того, они из вашей модели автоматически создают класс формы (<code>ModelForm</code>).</p> <div class="note"> -<p><strong>Примечание: </strong>В дополнение к отображениям для редактирования, описываемых здесь, существует также класс <a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#formview">FormView</a>, который по своему предназначению находится где-то между "простой" функцией отображения и другими обобщенными отображениями, то есть в каком-то смысле, в диапазоне: "гибкость" против "усилия при программировании". Применяя <code>FormView,</code> вы все еще нуждаетесь в создании класса <code>Form</code>, но вам не нужно реализовывать весь "стандартный" функционал работы с формой. Вместо этого, вы должны просто реализовать функцию, которая будет вызвана в тот момент, когда станет понятно, что получаемые из формы данные, "правильные" (валидны).</p> +<p><strong>Примечание: </strong>В дополнение к отображениям для редактирования, описываемых здесь, существует также класс <a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#formview">FormView</a>, который по своему предназначению находится где-то между "простой" функцией отображения и другими обобщёнными отображениями, то есть в каком-то смысле, в диапазоне: "гибкость" против "усилия при программировании". Применяя <code>FormView,</code> вы все ещё нуждаетесь в создании класса <code>Form</code>, но вам не нужно реализовывать весь "стандартный" функционал работы с формой. Вместо этого, вы должны просто реализовать функцию, которая будет вызвана в тот момент, когда станет понятно, что получаемые из формы данные, "правильные" (валидны).</p> </div> -<p>В данном разделе мы собираемся использовать обобщенные классы для редактирования, для того, чтобы создать страницы, который добавляют функционал создания, редактирования и удаления записей типа <code>Author</code> из нашей библиотеки — предоставляя базовый функционал некоторых частей административной части сайта (это может быть полезно для случаев, когда вам нужно создать административную часть сайта, которая, в отличие от стандартной, была бы более гибкой).</p> +<p>В данном разделе мы собираемся использовать обобщённые классы для редактирования, для того, чтобы создать страницы, который добавляют функционал создания, редактирования и удаления записей типа <code>Author</code> из нашей библиотеки — предоставляя базовый функционал некоторых частей административной части сайта (это может быть полезно для случаев, когда вам нужно создать административную часть сайта, которая, в отличие от стандартной, была бы более гибкой).</p> <h3 id="Отображения">Отображения</h3> @@ -630,9 +630,9 @@ class AuthorDelete(DeleteView): <h2 id="Итоги">Итоги</h2> -<p>Создание и управление формами может быть достаточно сложным! Django делает этот процесс намного проще, предоставляя прикладные механизмы объявления, рендеринга и проверки форм. Более того, Django предоставляет обобщенные классы редактирования форм, которые могут выполнять <em>практически любую</em> работу по созданию, редактированию и удалению записей, связанных с одиночной моделью.</p> +<p>Создание и управление формами может быть достаточно сложным! Django делает этот процесс намного проще, предоставляя прикладные механизмы объявления, рендеринга и проверки форм. Более того, Django предоставляет обобщённые классы редактирования форм, которые могут выполнять <em>практически любую</em> работу по созданию, редактированию и удалению записей, связанных с одиночной моделью.</p> -<p>Существует много чего еще, что можно делать с формами (ознакомьтесь со списком ниже), но теперь вы должны понимать как добавлять базовые формы и создавать код управления формой на вашем сайте. </p> +<p>Существует много чего ещё, что можно делать с формами (ознакомьтесь со списком ниже), но теперь вы должны понимать как добавлять базовые формы и создавать код управления формой на вашем сайте. </p> <h2 id="Смотрите_также">Смотрите также</h2> @@ -644,7 +644,7 @@ class AuthorDelete(DeleteView): <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/validation/">Класс Form и валидация поля</a> (Django docs)</li> <li><a href="https://docs.djangoproject.com/en/1.10/topics/class-based-views/generic-editing/">Управление классом Form из классов отображений</a> (Django docs)</li> <li><a href="https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/">Создание форм из моделей</a> (Django docs)</li> - <li><a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/">Обобщенные отображения для редактирования</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/">Обобщённые отображения для редактирования</a> (Django docs)</li> </ul> <p>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</p> |
