diff options
Diffstat (limited to 'files/ru/learn/server-side')
14 files changed, 241 insertions, 241 deletions
diff --git a/files/ru/learn/server-side/django/authentication/index.html b/files/ru/learn/server-side/django/authentication/index.html index a4baafeae5..c8508e97b7 100644 --- a/files/ru/learn/server-side/django/authentication/index.html +++ b/files/ru/learn/server-side/django/authentication/index.html @@ -61,7 +61,7 @@ original_slug: Learn/Server-side/Django/Аутентификация <p>Соответствующие настройки сделаны в параметрах <code>INSTALLED_APPS</code> и <code>MIDDLEWARE</code> файла проекта (<strong>locallibrary/locallibrary/settings.py</strong>), как показано ниже:</p> -<pre class="brush: python notranslate">INSTALLED_APPS = [ +<pre class="brush: python">INSTALLED_APPS = [ ... <strong> 'django.contrib.auth', </strong># Фреймворк аутентификации и моделей по умолчанию. <strong> 'django.contrib.contenttypes', # </strong>Django контент-типовая система (даёт разрешения, связанные с моделями). @@ -82,7 +82,7 @@ MIDDLEWARE = [ <div class="note"> <p><strong>Примечание</strong>: вы можете создавать пользователей программно, как показано ниже. Например, вам мог бы подойти данный способ в том случае, если вы разрабатываете интерфейс, который позволяет пользователям создавать их собственные аккаунты (вы не должны предоставлять доступ пользователям к административной панели вашего сайта).</p> -<pre class="brush: python notranslate">from django.contrib.auth.models import User +<pre class="brush: python">from django.contrib.auth.models import User # Создайте пользователя и сохраните его в базе данных user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword') @@ -144,7 +144,7 @@ user.save() <p>Добавьте следующее в нижней части проекта urls.py файл (<strong>locallibrary/locallibrary/urls.py</strong>) файл:</p> -<pre class="brush: python notranslate">#Add Django site authentication urls (for login, logout, password management) +<pre class="brush: python">#Add Django site authentication urls (for login, logout, password management) urlpatterns += [ path('accounts/', include('django.contrib.auth.urls')), ] @@ -157,7 +157,7 @@ urlpatterns += [ </div> <div class="note"> -<pre class="brush: python notranslate">accounts/ login/ [name='login'] +<pre class="brush: python">accounts/ login/ [name='login'] accounts/ logout/ [name='logout'] accounts/ password_change/ [name='password_change'] accounts/ password_change/done/ [name='password_change_done'] @@ -169,7 +169,7 @@ accounts/ reset/done/ [name='password_reset_complete']</pre> <p><span id="result_box" lang="ru"><span>Теперь попробуйте перейти к URL-адресу входа (<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>).</span> <span>Это приведёт к сбою снова, но с ошибкой, сообщающей вам, что нам не хватает требуемого шаблона (registration / login.html) в пути поиска шаблона.</span> <span>Вы увидите следующие строки, перечисленные в жёлтом разделе вверху:</span></span></p> -<pre class="brush: python notranslate">Exception Type: TemplateDoesNotExist +<pre class="brush: python">Exception Type: TemplateDoesNotExist Exception Value: <strong>registration/login.html</strong></pre> <p><span id="result_box" lang="ru"><span>Следующий шаг - создать каталог регистрации в пути поиска, а затем добавить файл login.html.</span></span></p> @@ -191,7 +191,7 @@ Exception Value: <strong>registration/login.html</strong></pre> <p>Чтобы сделать эти директории видимыми для загрузчика шаблонов (<span id="result_box" lang="ru"><span>т. е. помещать этот каталог в путь поиска шаблона</span></span>) откройте настройки проекта (<strong>/locallibrary/locallibrary/settings.py</strong>), и обновите в секции <code>TEMPLATES</code> строку <code>'DIRS'</code> как показано.</p> -<pre class="brush: python notranslate">TEMPLATES = [ +<pre class="brush: python">TEMPLATES = [ { ... <strong> </strong><strong>'DIRS': [os.path.join(BASE_DIR, 'templates')],</strong> @@ -207,7 +207,7 @@ Exception Value: <strong>registration/login.html</strong></pre> <p>Создайте новый HTML файл, названный /<strong>locallibrary/templates/registration/login.html</strong>. <span class="short_text" id="result_box" lang="ru"><span>дайте ему следующее содержание</span></span>:</p> -<pre class="brush: html line-numbers language-html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html line-numbers language-html">{% extends "base_generic.html" %} {% block content %} @@ -258,7 +258,7 @@ Exception Value: <strong>registration/login.html</strong></pre> <br> <span>Откройте настройки проекта (<strong>/locallibrary/locallibrary/settings.py</strong>) и добавьте текст ниже.</span> <span>Теперь, когда вы входите в систему, вы по умолчанию должны перенаправляться на домашнюю страницу сайта.</span></span></p> -<pre class="brush: python notranslate"># Redirect to home URL after login (Default redirects to /accounts/profile/) +<pre class="brush: python"># Redirect to home URL after login (Default redirects to /accounts/profile/) LOGIN_REDIRECT_URL = '/' </pre> @@ -268,7 +268,7 @@ LOGIN_REDIRECT_URL = '/' <br> <span>Создайте и откройте <strong>/locallibrary/templates/registration/logged_out.html</strong>.</span> <span>Скопируйте текст ниже:</span></span></p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} <p>Logged out!</p> @@ -290,7 +290,7 @@ LOGIN_REDIRECT_URL = '/' <p><span id="result_box" lang="ru"><span>Это форма, используемая для получения адреса электронной почты пользователя (для отправки пароля для сброса пароля).</span> <span>Создайте <strong>/locallibrary/templates/registration/password_reset_form.html</strong> и дайте ему следующее содержание:</span></span></p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} <form action="" method="post">{% csrf_token %} @@ -306,7 +306,7 @@ LOGIN_REDIRECT_URL = '/' <p>Эта форма отображается после того, как ваш адрес электронной почты будет собран. Создайте <strong>/locallibrary/templates/registration/password_reset_done.html</strong>, и дайте ему следующее содержание:</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} <p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p> {% endblock %} @@ -316,7 +316,7 @@ LOGIN_REDIRECT_URL = '/' <p>Этот шаблон предоставляет текст электронной почты HTML, содержащий ссылку на сброс, которую мы отправим пользователям. Создайте /locallibrary/templates/registration/password_reset_email.html и дайте ему следующее содержание:</p> -<pre class="brush: html notranslate">Someone asked for password reset for email \{{ email }}. Follow the link below: +<pre class="brush: html">Someone asked for password reset for email \{{ email }}. Follow the link below: \{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} </pre> @@ -324,7 +324,7 @@ LOGIN_REDIRECT_URL = '/' <p>На этой странице вы вводите новый пароль после нажатия ссылки в электронном письме с возвратом пароля. Создайте /locallibrary/templates/registration/password_reset_confirm.html и дайте ему следующее содержание:</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} @@ -361,7 +361,7 @@ LOGIN_REDIRECT_URL = '/' <p>Это последний шаблон сброса пароля, который отображается, чтобы уведомить вас о завершении сброса пароля. Создайте /locallibrary/templates/registration/password_reset_complete.html и дайте ему следующее содержание:</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} <h1>The password has been changed!</h1> @@ -383,7 +383,7 @@ LOGIN_REDIRECT_URL = '/' <div class="note"> <p><strong>Примечание</strong>: Система сброса пароля требует, чтобы ваш сайт поддерживал электронную почту, что выходит за рамки этой статьи, поэтому эта часть <strong>ещё не будет работать.</strong> Чтобы разрешить тестирование, поместите следующую строку в конец файла settings.py. Это регистрирует любые письма, отправленные на консоль (чтобы вы могли скопировать ссылку на сброс пароля с консоли).</p> -<pre class="brush: python notranslate">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +<pre class="brush: python">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' </pre> <p>Для получения дополнительной информации см. <a href="https://docs.djangoproject.com/en/2.0/topics/email/">Отправка email</a> (Django docs).</p> @@ -401,7 +401,7 @@ LOGIN_REDIRECT_URL = '/' <p>Откройте базовый шаблон (/locallibrary/catalog/templates/base_generic.html) и скопируйте следующий текст в sidebar блок непосредственно перед тегом шаблона endblock.</p> -<pre class="brush: python notranslate"> <ul class="sidebar-nav"> +<pre class="brush: python"> <ul class="sidebar-nav"> ... @@ -425,7 +425,7 @@ LOGIN_REDIRECT_URL = '/' <p>Если вы используете функциональные представления, самым простым способом ограничить доступ к вашим функциям является применение <code>login_required</code> декоратор к вашей функции просмотра, как показано ниже. Если пользователь вошёл в систему, ваш код просмотра будет выполняться как обычно. Если пользователь не вошёл в систему, это перенаправит URL-адрес входа, определённый в настройках проекта. (<code>settings.LOGIN_URL</code>), передав текущий абсолютный путь в качестве <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">next</span></font> параметра URL. Если пользователю удастся войти в систему, они будут возвращены на эту страницу, но на этот раз аутентифицированы.</p> -<pre class="brush: python notranslate">from django.contrib.auth.decorators import login_required +<pre class="brush: python">from django.contrib.auth.decorators import login_required @login_required def my_view(request): @@ -437,14 +437,14 @@ def my_view(request): <p>Аналогичным образом, самый простой способ ограничить доступ к зарегистрированным пользователям в ваших представлениях на основе классов - это производные от <code>LoginRequiredMixin</code>. Вы должны объявить этот mixin сначала в списке суперкласса, перед классом основного представления.</p> -<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin +<pre class="brush: python">from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): ...</pre> <p>Это имеет такое же поведение при переадресации, что и <code>login_required</code> декоратор. Вы также можете указать альтернативное местоположение для перенаправления пользователя, если он не аутентифицирован (<code>login_url</code>), и имя параметра URL вместо "<code>next</code>" , чтобы вставить текущий абсолютный путь (<code>redirect_field_name</code>).</p> -<pre class="brush: python notranslate">class MyView(LoginRequiredMixin, View): +<pre class="brush: python">class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to' </pre> @@ -463,21 +463,21 @@ class MyView(LoginRequiredMixin, View): <p>Откройте <strong>catalog/models.py</strong>, и импортируйте модель <code>User</code> из <code>django.contrib.auth.models</code> (добавьте это чуть ниже предыдущей строки импорта в верхней части файла, так <code>User</code> доступен для последующего кода, что позволяет использовать его):</p> -<pre class="brush: python notranslate">from django.contrib.auth.models import User +<pre class="brush: python">from django.contrib.auth.models import User </pre> <p>Затем добавьте поле <code>borrower</code> в модель <code>BookInstance</code>:</p> -<pre class="brush: python notranslate">borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) +<pre class="brush: python">borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) </pre> <p>Пока мы здесь, давайте добавим свойство, которое мы можем вызвать из наших шаблонов, чтобы указать, просрочен ли конкретный экземпляр книги. Хотя мы могли бы рассчитать это в самом шаблоне, использование свойства, как показано ниже, будет намного более эффективным. Добавьте это где-нибудь в верхней части файла:</p> -<pre class="syntaxbox notranslate">from datetime import date</pre> +<pre class="syntaxbox">from datetime import date</pre> <p>Теперь добавьте следующее определение свойства внутри класса BookInstance:</p> -<pre class="brush: python notranslate">@property +<pre class="brush: python">@property def is_overdue(self): if self.due_back and date.today() > self.due_back: return True @@ -489,7 +489,7 @@ def is_overdue(self): <p>Теперь, когда мы обновили наши модели, нам нужно будет внести новые изменения в проект, а затем применить эти миграции:</p> -<pre class="brush: bash notranslate">python3 manage.py makemigrations +<pre class="brush: bash">python3 manage.py makemigrations python3 manage.py migrate </pre> @@ -497,7 +497,7 @@ python3 manage.py migrate <p>Теперь откройте каталог <strong>catalog/admin.py</strong>, и добавьте поле <code>borrower</code> в класс <code>BookInstanceAdmin</code> , как в <code>list_display</code> , так и в полях <code>fieldsets</code> , как показано ниже. Это сделает поле видимым в разделе Admin, так что мы можем при необходимости назначить <code>User</code> в <code>BookInstance</code>.</p> -<pre class="brush: python notranslate">@admin.register(BookInstance) +<pre class="brush: python">@admin.register(BookInstance) class BookInstanceAdmin(admin.ModelAdmin): list_display = ('book', 'status'<strong>, 'borrower'</strong>, 'due_back', 'id') list_filter = ('status', 'due_back') @@ -525,7 +525,7 @@ class BookInstanceAdmin(admin.ModelAdmin): <p>Добавьте следующее в catalog/views.py:</p> -<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin +<pre class="brush: python">from django.contrib.auth.mixins import LoginRequiredMixin class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): """ @@ -544,7 +544,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Теперь откройте <strong>/catalog/urls.py</strong> и добавьте <code>url()</code> , указывая на приведённое выше представление (вы можете просто скопировать текст ниже в конец файла).</p> -<pre class="brush: python notranslate">urlpatterns += [ +<pre class="brush: python">urlpatterns += [ url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'), ]</pre> @@ -552,7 +552,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Теперь все, что нам нужно сделать для этой страницы, - это добавить шаблон. Сначала создайте файл шаблона <strong>/catalog/templates/catalog/bookinstance_list_borrowed_user.html</strong> и дайте ему следующее содержание:</p> -<pre class="brush: python notranslate">{% extends "base_generic.html" %} +<pre class="brush: python">{% extends "base_generic.html" %} {% block content %} <h1>Borrowed books</h1> @@ -582,7 +582,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Откройте базовый шаблон (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) и добавьте выделенную строку из sidebar, как показано на рисунке.</p> -<pre class="brush: python notranslate"> <ul class="sidebar-nav"> +<pre class="brush: python"> <ul class="sidebar-nav"> {% if user.is_authenticated %} <li>User: \{{ user.get_username }}</li> <strong> <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li></strong> @@ -607,7 +607,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Определение разрешений выполняется в разделе моделей "<code>class Meta</code>" , используется <code>permissions</code> поле. Вы можете указать столько разрешений, сколько необходимо в кортеже, причём каждое разрешение определяется во вложенном кортеже, содержащем имя разрешения и отображаемое значение разрешения. Например, мы можем определить разрешение, позволяющее пользователю отметить, что книга была возвращена, как показано здесь:</p> -<pre class="brush: python notranslate">class BookInstance(models.Model): +<pre class="brush: python">class BookInstance(models.Model): ... class Meta: ... @@ -621,7 +621,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Разрешения текущего пользователя хранятся в переменной шаблона, называемой <code>\{{ perms }}</code>. Вы можете проверить, имеет ли текущий пользователь определённое разрешение, используя конкретное имя переменной в соответствующем приложении «Django» - например, <code>\{{ perms.catalog.can_mark_returned }}</code> будет <code>True</code> если у пользователя есть это разрешение, а <code>False</code> - в противном случае. Обычно мы проверяем разрешение с использованием шаблона <code>{% if %}</code>, как показано в:</p> -<pre class="brush: python notranslate">{% if perms.catalog.<code>can_mark_returned</code> %} +<pre class="brush: python">{% if perms.catalog.<code>can_mark_returned</code> %} <!-- We can mark a BookInstance as returned. --> <!-- Perhaps add code to link to a "book return" view here. --> {% endif %} @@ -633,7 +633,7 @@ class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): <p>Функция в представлении с декоратором:</p> -<pre class="brush: python notranslate">from django.contrib.auth.decorators import permission_required +<pre class="brush: python">from django.contrib.auth.decorators import permission_required @permission_required('catalog.<code>can_mark_returned</code>') @permission_required('catalog.<code>can_edit</code>') @@ -642,7 +642,7 @@ def my_view(request): <p>Требуется разрешение mixin для представлений на основе классов.</p> -<pre class="brush: python notranslate">from django.contrib.auth.mixins import PermissionRequiredMixin +<pre class="brush: python">from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'catalog.<code>can_mark_returned</code>' diff --git a/files/ru/learn/server-side/django/deployment/index.html b/files/ru/learn/server-side/django/deployment/index.html index e3d7b75700..08cdb491fe 100644 --- a/files/ru/learn/server-side/django/deployment/index.html +++ b/files/ru/learn/server-side/django/deployment/index.html @@ -115,7 +115,7 @@ original_slug: Learn/Server-side/Django/Разворачивание <ul> <li><code>DEBUG</code>. При развёртывании сайта должен быть установлен в <code>False</code> (<code>DEBUG = False</code>). Тем самым, прекратится вывод важной отладочной информации.</li> <li><code>SECRET_KEY</code>. Это большое случайное число, применяемое для защиты от CRSF. Важно, чтобы ключ, используемый в продакшене, не указывался в исходном коде, и/или не запрашивался с другого сервера. Django рекомендует размещать значение ключа либо в переменной окружения, или в файле с доступом только на чтение. - <pre class="notranslate"># Чтение SECRET_KEY из переменной окружения + <pre># Чтение SECRET_KEY из переменной окружения import os SECRET_KEY = os.environ['SECRET_KEY'] @@ -131,7 +131,7 @@ with open('/etc/secret_key.txt') as f: <p>Откройте <strong>/locallibrary/settings.py</strong>, закомментируйте исходное значение <code>SECRET_KEY</code> и добавьте новые строки, как указано ниже <strong>жирным</strong>. В течении разработки, никаких переменных окружения определено не было, таким образом будут использоваться значения по умолчанию (не имеет значения какой ключ вы используете в процессе разработки, поскольку при развёртывании проекта вы будете использовать другой).</p> -<pre class="brush: python notranslate"># SECURITY WARNING: keep the secret key used in production secret! +<pre class="brush: python"># SECURITY WARNING: keep the secret key used in production secret! # SECRET_KEY = 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag' <strong>import os</strong> <strong>SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag')</strong> @@ -139,7 +139,7 @@ with open('/etc/secret_key.txt') as f: <p>Затем закомментируйте строку с настройкой <code>DEBUG</code>, а затем, добавьте новую, указанную ниже.</p> -<pre class="brush: python notranslate"># SECURITY WARNING: don't run with debug turned on in production! +<pre class="brush: python"># SECURITY WARNING: don't run with debug turned on in production! # DEBUG = True <strong>DEBUG = bool( os.environ.get('DJANGO_DEBUG', True) )</strong> </pre> @@ -152,7 +152,7 @@ with open('/etc/secret_key.txt') as f: <p>Весь перечень настроек для разворачивания вашего сайта находится по ссылке <a href="https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/">Deployment checklist</a> (Django docs). Кроме того, вы можете получить список настроек, выполнив в терминале команду:</p> -<pre class="brush: python notranslate">python3 manage.py check --deploy +<pre class="brush: python">python3 manage.py check --deploy </pre> <h2 id="Пример_Установка_LocalLibrary_на_Heroku">Пример: Установка LocalLibrary на Heroku</h2> @@ -247,11 +247,11 @@ with open('/etc/secret_key.txt') as f: <ol> <li>Установите git себе на компьютер (Вы можете найти версию для своей платформы <a href="https://git-scm.com/downloads">здесь</a>).</li> <li>Откройте командную строку (или терминал) и выполните в нём следующую команду, используя ссылку, которую вы получили с github: - <pre class="brush: bash notranslate">git clone https://github.com/<strong><em><your_git_user_id></em></strong>/django_local_library.git + <pre class="brush: bash">git clone https://github.com/<strong><em><your_git_user_id></em></strong>/django_local_library.git </pre> Это создаст подпапку (с содержанием вашего репозитория и именем вашего репозитория) внутри папки, в которой выполнялась команда.</li> <li>Перейдите в эту папку: - <pre class="brush: bash notranslate">cd django_local_library.git</pre> + <pre class="brush: bash">cd django_local_library.git</pre> </li> </ol> @@ -260,7 +260,7 @@ with open('/etc/secret_key.txt') as f: <ol> <li>Скопируйте ваше приложение в папку репозитория (все файлы с таким же уровнем, как у <strong>manage.py,</strong> <u><strong>БЕЗ </strong>папки проекта, в которой эти файлы находятся</u>).</li> <li>Откройте файл с расширением <strong>.gitignore </strong>в текстовом редакторе, вставьте в самый его конец строки, приведённые ниже, а затем сохраните (этот файл "говорит" о файлах, которые не должны быть загружены в git по умолчанию). - <pre class="notranslate"># Text backup files + <pre># Text backup files *.bak #Database @@ -269,10 +269,10 @@ with open('/etc/secret_key.txt') as f: <li> <p>Откройте командную строку или терминал и используйте <code>add</code> команду с флагом <code>-A</code>. Эта команда сохранит изменения в репозиторий:</p> - <pre class="brush: bash notranslate"><code>git add -A</code></pre> + <pre class="brush: bash"><code>git add -A</code></pre> </li> <li>Используйте команду <code>status</code>, что бы убедиться, что все файлы, которые вы собираетесь добавить верны (вы хотите включить исходные файлы, а не бинарные файлы, временные файлы и т. д.). В консоль выведется что то вроде этого: - <pre class="notranslate">> git status + <pre>> git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: @@ -286,10 +286,10 @@ Changes to be committed: new file: templates/registration/password_reset_form.html</pre> </li> <li>Теперь, зафиксируйте файлы в локальном репозитории: - <pre class="brush: bash notranslate">git commit -m "First version of application moved into github"</pre> + <pre class="brush: bash">git commit -m "First version of application moved into github"</pre> </li> <li>Синхронизируете свой локальный репозиторий с сайтом Github: - <pre class="notranslate">git push origin master</pre> + <pre>git push origin master</pre> </li> </ol> @@ -309,7 +309,7 @@ Changes to be committed: <p> Создайте файл с именем <code>Procfile</code> (без расширения) в корне нашего GitHub репозитории объявить типы процессов и точки входа приложения. Скопируйте в него следующий текст:</p> -<pre class="notranslate">web: gunicorn locallibrary.wsgi --log-file -</pre> +<pre>web: gunicorn locallibrary.wsgi --log-file -</pre> <p>«web:» сообщает Heroku, что это веб динамический и может быть отправлен HTTP-трафик. Процесс, который начнётся в этом динамически, - это gunicorn, который является популярным сервером веб-приложений, который рекомендует Heroku. Мы запускаем Gunicorn, используя конфигурационную информацию в модуле locallibrary.wsgi (созданный с помощью нашего скелета приложения: /locallibrary/wsgi.py).</p> @@ -321,7 +321,7 @@ Changes to be committed: <p>Установка <em>Gunicorn</em> локально в командной строке используя пакетный менеджер <em>pip</em> (которые мы установили когда <a href="/en-US/docs/Learn/Server-side/Django/development_environment">настраивали среду разработки</a>):</p> -<pre class="brush: bash notranslate">pip3 install gunicorn +<pre class="brush: bash">pip3 install gunicorn </pre> <h4 id="Настройка_Базы_Данных">Настройка Базы Данных</h4> @@ -336,14 +336,14 @@ Changes to be committed: <p>Установите dj-database-url локально, чтобы он стал частью наших требований к настройке Heroku на удалённом сервере:</p> -<pre class="notranslate">$ pip3 install dj-database-url +<pre>$ pip3 install dj-database-url </pre> <h5 id="settings.py">settings.py</h5> <p>Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла:</p> -<pre class="notranslate"># Heroku: Update database configuration from $DATABASE_URL. +<pre># Heroku: Update database configuration from $DATABASE_URL. import dj_database_url db_from_env = dj_database_url.config(conn_max_age=500) DATABASES['default'].update(db_from_env)</pre> @@ -363,7 +363,7 @@ DATABASES['default'].update(db_from_env)</pre> <p>Django будет использовать нашу базу данных SQLite локально по умолчанию, поскольку переменная среды DATABASE_URL не задана в нашей локальной среде. Если вы хотите полностью перейти на Postgres и использовать нашу бесплатную базу данных Heroku для разработки и производства, то вы можете. Например, чтобы установить psycopg2 и его зависимости локально в системе на базе Linux, вы должны использовать следующие команды bash / terminal:</p> -<pre class="brush: bash notranslate"><code>sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib</code> +<pre class="brush: bash"><code>sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib</code> pip3 install psycopg2 </pre> @@ -392,7 +392,7 @@ pip3 install psycopg2 <p>Откройте /locallibrary/settings.py и скопируйте следующую конфигурацию в нижнюю часть файла. BASE_DIR уже должен быть определён в вашем файле (STATIC_URL, возможно, уже был определён в файле, когда он был создан. В то время как это не причинит вреда, вы также можете удалить дублируемую предыдущую ссылку).</p> -<pre class="notranslate"># Static files (CSS, JavaScript, Images) +<pre># Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ # The absolute path to the directory where collectstatic will collect static files for deployment. @@ -419,14 +419,14 @@ STATIC_URL = '/static/' <p>Установите <em>WhiteNoise</em> локально, используя следующую команду:</p> -<pre class="notranslate">$ pip3 install whitenoise +<pre>$ pip3 install whitenoise </pre> <h5 id="settings.py_3">settings.py</h5> <p>Чтобы установить WhiteNoise в приложение Django, откройте /locallibrary/settings.py, найдите параметр MIDDLEWARE и добавьте WhiteNoiseMiddleware в верхней части списка, чуть ниже SecurityMiddleware:</p> -<pre class="notranslate">MIDDLEWARE = [ +<pre>MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', <strong>'whitenoise.middleware.WhiteNoiseMiddleware',</strong> 'django.contrib.sessions.middleware.SessionMiddleware', @@ -440,7 +440,7 @@ STATIC_URL = '/static/' <p>При желании вы можете уменьшить размер статических файлов при их обслуживании (это более эффективно). Просто добавьте следующее в конец /locallibrary/settings.py:</p> -<pre class="notranslate"># Simplified static file serving. +<pre># Simplified static file serving. # https://warehouse.python.org/project/whitenoise/ STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' </pre> @@ -449,11 +449,11 @@ STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' <p>Требования Python вашего веб-приложения должны храниться в файле requirements.txt в корневом каталоге вашего репозитория. После этого Heroku автоматически установит их при восстановлении вашей среды. Вы можете создать этот файл с помощью pip в командной строке (запустите в корне repo):</p> -<pre class="brush: bash notranslate">pip3 freeze > requirements.txt</pre> +<pre class="brush: bash">pip3 freeze > requirements.txt</pre> <p>После установки всех разных зависимостей выше, файл requirements.txt должен иметь <em>по меньшей мере</em> эти перечисленные элементы (хотя номера версий могут отличаться). Удалите любые другие зависимости, не перечисленные ниже, если вы явно не добавили их для этого приложения.</p> -<pre class="notranslate">dj-database-url==0.4.1 +<pre>dj-database-url==0.4.1 Django==1.10.2 gunicorn==19.6.0 <strong>psycopg2==2.6.2</strong> @@ -468,7 +468,7 @@ whitenoise==3.2.2 <p>Файл <strong>runtime.txt</strong>, если определён, говорит Heroku, какой язык программирования использовать. Создайте файл в корне репо и добавьте следующий текст:</p> -<pre class="notranslate">python-3.5.2</pre> +<pre>python-3.5.2</pre> <div class="note"> <p><strong>Примечание:</strong> Heroku поддерживает только небольшое количество <a href="https://devcenter.heroku.com/articles/python-support#supported-python-runtimes">Python runtimes</a>. (на момент написания статьи, в том числе и выше). Heroku будет использовать поддерживаемую среду выполнения независимо от значения, указанного в этом файле.</p> @@ -478,13 +478,13 @@ whitenoise==3.2.2 <p>Далее мы сохраним все наши изменения в Github. В терминале (whist внутри нашего репозитория) введите следующие команды:</p> -<pre class="brush: python notranslate">git add -A +<pre class="brush: python">git add -A git commit -m "Added files and changes required for deployment to heroku" git push origin master</pre> <p>Прежде чем продолжить, дайте возможность проверить сайт снова локально и убедиться, что это не повлияло ни на одно из наших изменений выше. Запустите веб-сервер разработки как обычно, а затем проверьте, работает ли сайт, как вы ожидаете в своём браузере.</p> -<pre class="brush: bash notranslate">python3 manage.py runserver</pre> +<pre class="brush: bash">python3 manage.py runserver</pre> <p>Теперь мы должны быть готовы начать развёртывание LocalLibrary на Heroku.</p> @@ -506,14 +506,14 @@ git push origin master</pre> <p>После установки клиента вам будут доступны команды. Например, чтобы получить справку о клиенте:</p> -<pre class="brush: bash notranslate">heroku help +<pre class="brush: bash">heroku help </pre> <h3 id="Создание_и_загрузка_веб-сайта">Создание и загрузка веб-сайта</h3> <p>Чтобы создать приложение, мы запускаем команду «create» в корневом каталоге нашего репозитория. Это создаёт git remote («указатель на удалённый репозиторий»), названный heroku в нашей локальной среде git.</p> -<pre class="brush: bash notranslate">heroku create</pre> +<pre class="brush: bash">heroku create</pre> <div class="note"> <p><strong>Примечание:</strong> вы можете назвать удалённый, если хотите, указав значение после «create». Если вы этого не сделаете, вы получите случайное имя. Имя используется в URL-адресе по умолчанию.</p> @@ -521,19 +521,19 @@ git push origin master</pre> <p>Затем мы можем подтолкнуть наше приложение в репозиторий heroku как показано ниже. Это позволит загрузить приложение, упаковать его в dyno, запустить collectstatic, и запустить сам сайт.</p> -<pre class="brush: bash notranslate">git push heroku master</pre> +<pre class="brush: bash">git push heroku master</pre> <p>Если нам повезёт, приложение «заработает» на сайте, но оно не будет работать должным образом, потому что мы не настроили таблицы базы данных для использования нашим приложением. Для этого нам нужно использовать команду <code>heroku run</code> и запустить "<a href="https://devcenter.heroku.com/articles/deploying-python#one-off-dynos">one off dyno</a>" для выполнения операции переноса. Введите в терминал следующую команду:</p> -<pre class="brush: bash notranslate">heroku run python manage.py migrate</pre> +<pre class="brush: bash">heroku run python manage.py migrate</pre> <p>Мы также должны будем иметь возможность добавлять книги и авторов, поэтому давайте также создадим суперпользователя, снова используя одноразовый динамический режим:</p> -<pre class="brush: bash notranslate">heroku run python manage.py createsuperuser</pre> +<pre class="brush: bash">heroku run python manage.py createsuperuser</pre> <p>Как только это будет завершено, мы можем посмотреть сайт. Он должен работать, хотя в нем ещё нет книг. Чтобы открыть браузер на новом веб-сайте, используйте команду:</p> -<pre class="brush: bash notranslate">heroku open</pre> +<pre class="brush: bash">heroku open</pre> <p>Создайте несколько книг на сайте администратора и проверьте, работает ли сайт, как вы ожидаете.</p> @@ -541,7 +541,7 @@ git push origin master</pre> <p>Вы можете проверить дополнения в своём приложении, используя <code>heroku addons</code> команду. Это будет список всех аддонов, их ценовая категория и состояние.</p> -<pre class="brush: bash notranslate">>heroku addons +<pre class="brush: bash">>heroku addons Add-on Plan Price State ───────────────────────────────────────── ───────── ───── ─────── @@ -550,7 +550,7 @@ heroku-postgresql (postgresql-flat-26536) hobby-dev free created <p>Здесь мы видим, что у нас есть только одна надстройка, база данных postgres SQL. Это бесплатно и автоматически создаётся при создании приложения. Вы можете открыть веб-страницу, чтобы более подробно изучить надстройку базы данных (или любое другое дополнение), используя следующую команду:</p> -<pre class="brush: bash notranslate">heroku addons:open heroku-postgresql +<pre class="brush: bash">heroku addons:open heroku-postgresql </pre> <p>Другие команды позволяют создавать, уничтожать, обновлять и понижать аддоны (используя аналогичный синтаксис для открытия). Для получения дополнительной информации см. <a href="https://devcenter.heroku.com/articles/managing-add-ons">Managing Add-ons</a> (Heroku docs).</p> @@ -559,7 +559,7 @@ heroku-postgresql (postgresql-flat-26536) hobby-dev free created <p>Вы можете проверить конфигурационные переменные для сайта, используя команду <code>heroku config</code>. Ниже вы можете видеть, что у нас есть только одна переменная <code>DATABASE_URL</code> , используемая для настройки нашей базы данных.</p> -<pre class="brush: bash notranslate">>heroku config +<pre class="brush: bash">>heroku config === locallibrary Config Vars DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-201-144.compute-1.amazonaws.com:5432/dbftm4qgh3kda3</pre> @@ -572,7 +572,7 @@ DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-20 <p>Мы устанавливаем <code>DJANGO_SECRET_KEY</code> используя команду <code>config:set</code> (как показано ниже). Не забудьте использовать свой секретный ключ!</p> -<pre class="brush: bash notranslate">>heroku config:set DJANGO_SECRET_KEY=eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&= +<pre class="brush: bash">>heroku config:set DJANGO_SECRET_KEY=eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&= Setting DJANGO_SECRET_KEY and restarting locallibrary... done, v7 DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh @@ -580,20 +580,20 @@ DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh <p>Аналогично мы устанавливаем <code>DJANGO_DEBUG</code>:</p> -<pre class="brush: bash notranslate">>heroku config:set <code>DJANGO_DEBUG='' +<pre class="brush: bash">>heroku config:set <code>DJANGO_DEBUG='' Setting DJANGO_DEBUG and restarting locallibrary... done, v8</code></pre> <p>Если вы посетите веб-сайт сейчас, вы получите ошибку "Bad request" , потому что в <a href="https://docs.djangoproject.com/en/1.10/ref/settings/#allowed-hosts">ALLOWED_HOSTS</a> надо внести параметры, если у вас <code>DEBUG=False</code> (в качестве меры безопасности). Откройте <strong>/locallibrary/settings.py</strong> и измените <code>ALLOWED_HOSTS</code> для включения вашего базового URL-адреса приложения (например, 'locallibrary1234.herokuapp.com') URL, который вы обычно используете на локальном сервере разработки.</p> -<pre class="brush: python notranslate">ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1'] +<pre class="brush: python">ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1'] # For example: # ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com','127.0.0.1'] </pre> <p>Затем сохраните настройки и передайте их в репозиторий Github и в Heroku:</p> -<pre class="brush: bash notranslate">git add -A +<pre class="brush: bash">git add -A git commit -m 'Update ALLOWED_HOSTS with site and development server URL' git push origin master git push heroku master</pre> @@ -606,7 +606,7 @@ git push heroku master</pre> <p>Клиент Heroku предоставляет несколько инструментов для отладки:</p> -<pre class="brush: bash notranslate">heroku logs # Show current logs +<pre class="brush: bash">heroku logs # Show current logs heroku logs --tail # Show current logs and keep updating with any new results heroku config:set DEBUG_COLLECTSTATIC=1 # Add additional logging for collectstatic (this tool is run automatically during a build) heroku ps #Display dyno status diff --git a/files/ru/learn/server-side/django/development_environment/index.html b/files/ru/learn/server-side/django/development_environment/index.html index 199f16badb..5265e95819 100644 --- a/files/ru/learn/server-side/django/development_environment/index.html +++ b/files/ru/learn/server-side/django/development_environment/index.html @@ -115,19 +115,19 @@ translation_of: Learn/Server-side/Django/development_environment <p>Ubuntu Linux включает в себя Python 3 по умолчанию. Вы можете удостовериться в этом, выполнив следующую команду в терминале:</p> -<pre class="notranslate">python3 -V +<pre>python3 -V Python 3.5.2</pre> <p>Однако, инструмент Python Package Index, при помощи которого вам нужно будет установить пакеты для Python 3 (включая Django), по умолчанию <strong>не установлен</strong>. Вы можете установить pip3 через терминал bash при помощи:</p> -<pre class="notranslate">sudo apt-get install python3-pip +<pre>sudo apt-get install python3-pip </pre> <h3 id="Mac_OS_X">Mac OS X</h3> <p>Mac OS X "El Capitan" не включает Python 3. Вы можете удостовериться в этом, выполнив следующую команду в терминале:</p> -<pre class="notranslate">python3 -V +<pre>python3 -V -bash: python3: command not found</pre> <p>Вы можете легко установить Python 3 (вместе с инструментом <em>pip3</em>) с<a href="https://www.python.org/"> python.org</a>:</p> @@ -144,13 +144,13 @@ translation_of: Learn/Server-side/Django/development_environment <p>Удостовериться в успешной установке вы можете проверкой на наличие <em>Python 3</em>, как показано ниже:</p> -<pre class="notranslate">python3 -V +<pre>python3 -V Python 3.5.20 </pre> <p>Подобным образом вы можете проверить установку <em>pip3</em>, отобразив список доступных пакетов:</p> -<pre class="notranslate">pip3 list</pre> +<pre>pip3 list</pre> <h3 id="Windows_10">Windows 10</h3> @@ -168,13 +168,13 @@ translation_of: Learn/Server-side/Django/development_environment <p>После этого вы сможете подтвердить успешную установку Python путём выполнения следующего текста в командной строке:</p> -<pre class="notranslate">py -3 -V +<pre>py -3 -V Python 3.5.2 </pre> <p>Установщик Windows включает в себя <em>pip3</em> (менеджер пакетов Python) по умолчанию. Вы можете отобразить список установленных пакетов, как показано далее:</p> -<pre class="notranslate">pip list +<pre>pip list </pre> <div class="note"> @@ -193,12 +193,12 @@ translation_of: Learn/Server-side/Django/development_environment <p>Установите инструмент при помощи pip3:</p> -<pre class="notranslate"><code>sudo pip3 install virtualenvwrapper</code> +<pre><code>sudo pip3 install virtualenvwrapper</code> </pre> <p>Затем добавьте следующие строки в конец файла загрузки программной оболочки (shell) (это скрытый файл в вашей домашней директории с именем <strong>.bashrc</strong>). Они устанавливают расположение виртуальных сред, расположение каталога разрабатываемого проекта и расположение установленного с этим пакетом скрипта.</p> -<pre class="notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs +<pre><code>export WORKON_HOME=$HOME/.virtualenvs export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 ' export PROJECT_HOME=$HOME/Devel @@ -207,12 +207,12 @@ source /usr/local/bin/virtualenvwrapper.sh</code> <p>Затем перезагрузите файл загрузки, выполнив в терминале следующую команду:</p> -<pre class="notranslate"><code>source ~/.bashrc</code> +<pre><code>source ~/.bashrc</code> </pre> <p>В этот момент вы должны увидеть запуск группы скриптов, как показано ниже:</p> -<pre class="notranslate"><code>virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject +<pre><code>virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject ... virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate @@ -228,12 +228,12 @@ virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_detail <p>Установите инструмент при помощи pip3:</p> -<pre class="notranslate"><code>sudo pip3 install virtualenvwrapper</code> +<pre><code>sudo pip3 install virtualenvwrapper</code> </pre> <p>Затем добавьте следующие строки в конец вашего файла загрузки программной оболочки:</p> -<pre class="notranslate"><code>export WORKON_HOME=$HOME/.virtualenvs +<pre><code>export WORKON_HOME=$HOME/.virtualenvs export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 export PROJECT_HOME=$HOME/Devel source /usr/local/bin/virtualenvwrapper.sh</code> @@ -252,7 +252,7 @@ source /usr/local/bin/virtualenvwrapper.sh</code> -<pre class="notranslate"><code>cd ~ # Navigate to my home directory +<pre><code>cd ~ # Navigate to my home directory ls -la #List the content of the directory. You should see .bash_profile nano .bash_profile # Open the file in the nano text editor, within the terminal # Scroll to the end of the file, and copy in the lines above @@ -262,7 +262,7 @@ nano .bash_profile # Open the file in the nano text editor, within the terminal <p>После этого перезагрузите файл загрузки путём выполнения следующей команды в терминале:</p> -<pre class="notranslate"><code>source ~/.bash_profile</code> +<pre><code>source ~/.bash_profile</code> </pre> <p>В этот момент вы должны увидеть запуск группы скриптов (те же скрипты, что и в случае установки на Ubuntu).</p> @@ -273,7 +273,7 @@ nano .bash_profile # Open the file in the nano text editor, within the terminal <p>Установка <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> ещё более проста, чем установка <em>virtualenvwrapper</em>, потому что вам не нужно настраивать расположения сохранения информации о виртуальной среде инструментом (эти значения заданы по умолчанию). Все, что вам нужно сделать, это запустить следующую команду в командной строке:</p> -<pre class="notranslate"><code>pip3 install virtualenvwrapper-win</code></pre> +<pre><code>pip3 install virtualenvwrapper-win</code></pre> <p>Теперь вы можете создать новую виртуальную среду при помощи команды <code>mkvirtualen</code>.</p> @@ -283,7 +283,7 @@ nano .bash_profile # Open the file in the nano text editor, within the terminal <p>Теперь вы можете создать новую виртуальную среду при помощи команды <code>mkvirtualenv</code>. Во время запуска команды вы увидите установку виртуальной среды (конкретные результаты команды очень зависят от платформы). После выполнения команды активируется новая виртуальная среда — заметить это вы можете по тому, что началом ввода будет название виртуальной среды в круглых скобках (как показано ниже).</p> -<pre class="notranslate"><code>$ mkvirtualenv my_django_environment +<pre><code>$ mkvirtualenv my_django_environment Running virtualenv with interpreter /usr/bin/python3 ... virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details (my_django_environment) ubuntu@ubuntu:~$</code></pre> @@ -309,12 +309,12 @@ virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get <p>После создания виртуальной среды и вызова <code>workon</code> для входа в неё вы можете использовать <em>pip3 </em>для установки Django. </p> -<pre class="notranslate">pip3 install django +<pre>pip3 install django </pre> <p>Вы можете проверить установку Django, выполнив следующую команду (она просто проверяет, что Python может найти модуль Django):</p> -<pre class="notranslate"># Linux/Mac OS X +<pre># Linux/Mac OS X python3 -m django --version 1.10.10 @@ -335,18 +335,18 @@ py -3 -m django --version <p>Указанная выше проверка работает, но не представляет особого интереса.Более интересная проверка заключается в создании шаблона проекта и проверки его работы. Для её выполнения перейдите в командной строке/терминале в место, где планируете сохранять приложения Django. Создайте папку для теста и перейдите в неё.</p> -<pre class="notranslate">mkdir django_test +<pre>mkdir django_test cd django_test </pre> <p>Затем вы можете создать шаблон сайта "<em>mytestsite</em>" при помощи инструмента <strong>django-admin</strong>. После создания сайта вы можете перейти в папку, где найдёте основной скрипт для управления проектами с именем <strong>manage.py</strong>.</p> -<pre class="notranslate">django-admin startproject mytestsite +<pre>django-admin startproject mytestsite cd mytestsite</pre> <p>Мы можем запустить веб-сервер разработки из этой папки при помощи <strong>manage.py</strong> и команды <code>runserver</code>, как показано ниже.</p> -<pre class="notranslate">$ <strong>python3 manage.py runserver </strong> +<pre>$ <strong>python3 manage.py runserver </strong> Performing system checks... System check identified no issues (0 silenced). diff --git a/files/ru/learn/server-side/django/forms/index.html b/files/ru/learn/server-side/django/forms/index.html index 6652e56297..9b2c9a5ed3 100644 --- a/files/ru/learn/server-side/django/forms/index.html +++ b/files/ru/learn/server-side/django/forms/index.html @@ -50,7 +50,7 @@ translation_of: Learn/Server-side/Django/Forms <p>Форма описывается на языке HTML как набор элементов, расположенных внутри парных тэгов <code><form>...</form></code>. Любая форма содержит как минимум одно поле-тэг <code>input</code> типа <code>type="submit"</code>.</p> -<pre class="brush: html notranslate"><form action="/team_name_url/" method="post"> +<pre class="brush: html"><form action="/team_name_url/" method="post"> <label for="team_name">Enter name: </label> <input id="team_name" type="text" name="name_field" value="Default name for team."> <input type="submit" value="OK"> @@ -129,7 +129,7 @@ translation_of: Learn/Server-side/Django/Forms <p>Для того, чтобы создать класс с возможностями базового класса <code>Form</code> мы должны импортировать библиотеку <code>forms</code>, наследовать наш класс от класса <code>Form</code>, а затем объявить поля формы. Таким образом, самый простой класс формы в нашем случае будет иметь вид, показанный ниже:</p> -<pre class="brush: python notranslate">from django import forms +<pre class="brush: python">from django import forms class RenewBookForm(forms.Form): renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).") @@ -160,7 +160,7 @@ class RenewBookForm(forms.Form): <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 +<pre class="brush: python">from django import forms <strong>from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ @@ -201,7 +201,7 @@ class RenewBookForm(forms.Form): <p>Перед созданием отображения давайте добавим соответствующую конфигурацию URL-адреса для страницы обновления книг. Скопируйте следующий фрагмент в нижнюю часть файла<strong> locallibrary/catalog/urls.py</strong>.</p> -<pre class="brush: python notranslate">urlpatterns += [ +<pre class="brush: python">urlpatterns += [ url(r'^book/(?P<pk>[-\w]+)/renew/$', views.renew_book_librarian, name='renew-book-librarian'), ]</pre> @@ -219,7 +219,7 @@ class RenewBookForm(forms.Form): <p>Процесс обновления книги приводит к изменению информации в базе данных, таким образом, в соответствии с нашими соглашениями, в таком случае мы должны применять запрос типа <code>POST</code>. Фрагмент кода, представленный ниже, показывает (наиболее общую) схему работы для таких запросов. </p> -<pre class="brush: python notranslate">from django.shortcuts import get_object_or_404 +<pre class="brush: python">from django.shortcuts import get_object_or_404 from django.http import HttpResponseRedirect from django.urls import reverse import datetime @@ -263,7 +263,7 @@ def renew_book_librarian(request, pk): <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) +<pre class="brush: python"> book_inst = get_object_or_404(BookInstance, pk=pk) # Если это GET (или другой метод), тогда создаём форму по умолчанию <strong>else:</strong> @@ -276,7 +276,7 @@ def renew_book_librarian(request, pk): <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) +<pre class="brush: python"> book_inst = get_object_or_404(BookInstance, pk=pk) # Если данный запрос типа POST, тогда if request.method == 'POST': @@ -309,7 +309,7 @@ def renew_book_librarian(request, pk): <p>Окончательный вид отображения показан ниже. Пожалуйста, скопируйте данный текст в нижнюю часть файла <strong>locallibrary/catalog/views.py</strong>.</p> -<pre class="notranslate"><strong>from django.contrib.auth.decorators import permission_required</strong> +<pre><strong>from django.contrib.auth.decorators import permission_required</strong> from django.shortcuts import get_object_or_404 from django.http import HttpResponseRedirect @@ -352,7 +352,7 @@ def renew_book_librarian(request, pk): <p>Создайте шаблон, на который ссылается наше отображение (<strong>/catalog/templates/catalog/book_renew_librarian.html</strong>) и скопируйте в него код, указанный ниже:</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} <h1>Renew: \{{bookinst.book.title}}</h1> @@ -379,7 +379,7 @@ def renew_book_librarian(request, pk): <p>Все что осталось, это указать переменную <code>\{{form}}</code>, которую мы передали в шаблон в словаре контекста. Возможно это вас не удивит, но таким образом мы предоставим возможность форме отрендерить свои поля с их метками, виджетами и дополнительными текстами, и в результате мы получим следующее:</p> -<pre class="brush: html notranslate"><tr> +<pre class="brush: html"><tr> <th><label for="id_renewal_date">Renewal date:</label></th> <td> <input id="id_renewal_date" name="renewal_date" type="text" value="2016-11-08" required /> @@ -395,7 +395,7 @@ def renew_book_librarian(request, pk): <p>Если вы ввели неправильную дату, то на странице вы должны получить список сообщений об ошибках (показано жирным ниже).</p> -<pre class="brush: html notranslate"><tr> +<pre class="brush: html"><tr> <th><label for="id_renewal_date">Renewal date:</label></th> <td> <strong> <ul class="errorlist"> @@ -427,7 +427,7 @@ def renew_book_librarian(request, pk): <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> +<pre class="brush: html">{% if perms.catalog.can_mark_returned %}- <a href="{% url 'renew-book-librarian' bookinst.id %}">Renew</a> {% endif %}</pre> <div class="note"> <p><strong>Примечание</strong>: Помните что, для того чтобы перейти на страницу обновления книги, ваш тестовый логин должен иметь разрешение доступа типа "<code>catalog.can_mark_returned</code>"(возможно надо воспользоваться вашим аккаунтом для суперпользователя).</p> @@ -457,7 +457,7 @@ def renew_book_librarian(request, pk): <p>Базовая реализация <code>ModelForm</code> содержит тоже поле как и ваш предыдущий класс формы <code>RenewBookForm</code>, что и показано ниже. Все что вам необходимо сделать, - внутри вашего нового класса добавить класс <code>Meta</code> и связать его с моделью <code>model</code> (<code>BookInstance</code>), а затем перечислить поля модели в поле <code>fields</code> которые должны быть включены в форму (вы можете включить все поля при помощи <code>fields = '__all__'</code>, или можно воспользоваться полем <code>exclude</code> (вместо <code>fields</code>), чтобы определить поля модели, которые <em>не</em> нужно включать).</p> -<pre class="brush: python notranslate">from django.forms import ModelForm +<pre class="brush: python">from django.forms import ModelForm from .models import BookInstance class RenewBookModelForm(ModelForm): @@ -472,7 +472,7 @@ class RenewBookModelForm(ModelForm): <p>Оставшаяся часть информации касается объявления полей модели (то есть, текстовых меток, виджетов, текстов, сообщений об ошибках). Если они недостаточно "правильные", то тогда мы можем переопределить их в нашем классе <code>Meta</code> при помощи словаря, содержащего поле, которое надо изменить и его новое значение. Например, в нашей форме мы могли бы поменять текст метки для поля "<em>Renewal date</em>" (вместо того, чтобы оставить текст по умолчанию: <em>Due date</em>), а кроме того мы хотим написать другой вспомогательный текст. Класс <code>Meta</code>, представленный ниже, показывает вам, как переопределить данные поля. Кроме того, при необходимости, вы можете установить значения для виджетов <code>widgets</code> и сообщений об ошибках <code>error_messages</code>.</p> -<pre class="brush: python notranslate">class Meta: +<pre class="brush: python">class Meta: model = BookInstance fields = ['due_back',] <strong> labels = { 'due_back': _('Renewal date'), } @@ -481,7 +481,7 @@ class RenewBookModelForm(ModelForm): <p>Чтобы добавить валидацию, вы можете использовать тот же способ как и для класса <code>Form</code> — вы определяете функцию с именем <code>clean_<em>field_name</em>()</code> из которой выбрасываете исключение <code>ValidationError</code>, если это необходимо. Единственным отличием от нашей оригинальной формы будет являться то, что поле модели имеет имя <code>due_back</code>, а не "<code>renewal_date</code>".</p> -<pre class="brush: python notranslate">from django.forms import ModelForm +<pre class="brush: python">from django.forms import ModelForm from .models import BookInstance class RenewBookModelForm(ModelForm): @@ -522,7 +522,7 @@ class RenewBookModelForm(ModelForm): <p>Откройте файл отображений (<strong>locallibrary/catalog/views.py</strong>) и добавьте следующий код в его нижнюю часть:</p> -<pre class="brush: python notranslate">from django.views.generic.edit import CreateView, UpdateView, DeleteView +<pre class="brush: python">from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.urls import reverse_lazy from .models import Author @@ -551,7 +551,7 @@ class AuthorDelete(DeleteView): <p>Создайте файл шаблона <strong>locallibrary/catalog/templates/catalog/author_form.html</strong> и скопируйте в него следующий текст.</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} @@ -569,7 +569,7 @@ class AuthorDelete(DeleteView): <p>Отображения "удалить" ожидает "найти" шаблон с именем формата <em>model_name</em><strong>_confirm_delete.html</strong> (и снова, вы можете изменить суффикс при помощи поля отображения<code>template_name_suffix</code>). Создайте файл шаблона <strong>locallibrary/catalog/templates/catalog/author_confirm_delete</strong><strong>.html</strong> и скопируйте в него текст, указанный ниже.</p> -<pre class="brush: html notranslate">{% extends "base_generic.html" %} +<pre class="brush: html">{% extends "base_generic.html" %} {% block content %} @@ -589,7 +589,7 @@ class AuthorDelete(DeleteView): <p>Откройте файл конфигураций URL-адресов (<strong>locallibrary/catalog/urls.py</strong>) и добавьте в его нижнюю часть следующие настройки:</p> -<pre class="brush: python notranslate">urlpatterns += [ +<pre class="brush: python">urlpatterns += [ url(r'^author/create/$', views.AuthorCreate.as_view(), name='author_create'), url(r'^author/(?P<pk>\d+)/update/$', views.AuthorUpdate.as_view(), name='author_update'), url(r'^author/(?P<pk>\d+)/delete/$', views.AuthorDelete.as_view(), name='author_delete'), diff --git a/files/ru/learn/server-side/django/introduction/index.html b/files/ru/learn/server-side/django/introduction/index.html index 34fcd1da21..b94853398f 100644 --- a/files/ru/learn/server-side/django/introduction/index.html +++ b/files/ru/learn/server-side/django/introduction/index.html @@ -112,7 +112,7 @@ original_slug: Learn/Server-side/Django/Введение <p>Сопоставитель URL-адресов обычно содержится в файле <strong>urls.py</strong>. В примере ниже сопоставитель (<code>urlpatterns</code>) определяет список сопоставлений между<em>маршрутами </em>(определёнными URL-<em>шаблонами</em>) и соответствующими функциями отображения (view). Если получен HTTP-запрос, который имеет URL-адрес, соответствующий определённому шаблону, то затем будет вызвана связанная функция отображения (view) и передана в запрос.</p> -<pre class="notranslate">urlpatterns = [ +<pre>urlpatterns = [ <strong>path('admin/', admin.site.urls), </strong>path('book/<int:id>/', views.book_detail, name='book_detail'), path('catalog/', include('catalog.urls')), @@ -131,7 +131,7 @@ original_slug: Learn/Server-side/Django/Введение <p>В приведённом ниже примере показана минимальная функция представления <code>index()</code>, которая могла быть вызвана нашим сопоставителем URL-адресов в предыдущем разделе. Как и все функции отображения (view), она получает объект <code>HttpRequest</code> в качестве параметра (<code>request</code>) и возвращает объект <code>HttpResponse</code>. В этом случае мы ничего не делаем с запросом, и наш ответ просто возвращает жёстко запрограммированную строку. Мы покажем вам запрос, который делает что-то более интересное в следующем разделе.</p> -<pre class="brush: python notranslate">## filename: views.py (Django view functions) +<pre class="brush: python">## filename: views.py (Django view functions) from django.http import HttpResponse @@ -162,7 +162,7 @@ def index(request): <p>В приведённом ниже фрагменте кода показана очень простая модель Django для объекта <code>Team</code>. Класс <code>Team</code> наследуется от класса <code>models.Model</code>. Он определяет имя команды и командный уровень в качестве полей символов и задаёт максимальное количество символов, которые могут быть сохранены для каждой записи. <code>Team_level</code> может быть одним из нескольких значений, поэтому мы определяем его как поле выбора и предоставляем сопоставление между отображаемыми вариантами и хранимыми данными вместе со значением по умолчанию.</p> -<pre class="brush: python notranslate"># filename: models.py +<pre class="brush: python"># filename: models.py from django.db import models @@ -194,7 +194,7 @@ class Team(models.Model): <p>Фрагмент кода показывает функцию view (обработчик ресурсов) для отображения всех команд U09. Выделенная жирным строка показывает, как мы можем использовать модель API-запросов для того, чтобы отфильтровать все записи, где поле <code>team_level</code> в точности содержит текст 'U09' (обратите внимание, как эти критерии передаются функции <code>filter()</code> в качестве аргумента с именем поля и типом соответствия, разделённым двойным подчёркиванием: <strong>team_level__exact</strong>). </p> -<pre class="brush: python notranslate">## filename: views.py +<pre class="brush: python">## filename: views.py from django.shortcuts import render from .models import Team @@ -216,7 +216,7 @@ def index(request): <p>Фрагмент кода показывает, как может выглядеть HTML-шаблон, вызванный функцией <code>render()</code> из предыдущего раздела. Этот шаблон был написан с предположением, что во время отрисовки он будет иметь доступ к переменной списка, названной <code>youngest_teams</code> (содержащейся в контекстной переменной внутри функции <code>render()</code> выше). Внутри скелета HTML мы имеем выражение, которое сначала проверяет, существует ли переменная <code>youngest_teams</code>, а затем повторяет её в цикле <code>for</code>. При каждом повторе шаблон отображает значение <code>team_name</code> каждой команды в элементе <code>{{htmlelement("li")}}</code>.</p> -<pre class="notranslate">## filename: best/templates/best/index.html +<pre>## filename: best/templates/best/index.html <!DOCTYPE html> <html lang="en"> diff --git a/files/ru/learn/server-side/django/models/index.html b/files/ru/learn/server-side/django/models/index.html index 8e05924833..84f8b261d2 100644 --- a/files/ru/learn/server-side/django/models/index.html +++ b/files/ru/learn/server-side/django/models/index.html @@ -63,7 +63,7 @@ translation_of: Learn/Server-side/Django/Models <p>Модели обычно определяются в приложении <strong>models.py</strong>. Они реализуются как подклассы <code>django.db.models.Model</code>, и могут включать поля, методы и метаданные. В приведённом ниже фрагменте кода показана «типичная» модель, названная <code>MyModelName</code>:</p> -<pre class="notranslate">from django.db import models +<pre>from django.db import models class MyModelName(models.Model): """ @@ -97,7 +97,7 @@ class MyModelName(models.Model): <p>Модель может иметь произвольное количество полей любого типа - каждый представляет столбец данных, который мы хотим сохранить в одной из наших таблиц базы данных. Каждая запись (строка) базы данных будет состоять из одного значения каждого поля. Давайте рассмотрим приведённый выше пример:</p> -<pre class="brush: js notranslate">my_field_name = models.CharField(max_length=20, help_text="Enter field documentation")</pre> +<pre class="brush: js">my_field_name = models.CharField(max_length=20, help_text="Enter field documentation")</pre> <p>Наш вышеприведённый пример имеет одно поле, называемое my_<code>field_name</code>, типа <code>models.CharField</code> — что означает, что это поле будет содержать строки буквенно-цифровых символов. Типы полей назначаются с использованием определённых классов, которые определяют тип записи, которая используется для хранения данных в базе данных, а также критерии проверки, которые должны использоваться, когда значения получены из формы HTML (то есть, что составляет действительное значение). Типы полей также могут принимать аргументы, которые дополнительно определяют, как поле хранится или может использоваться. В этом случае мы даём нашему полю два аргумента:</p> @@ -148,7 +148,7 @@ class MyModelName(models.Model): <p>Вы можете объявить метаданные на уровне модели для своей модели, объявив класс Meta, как показано на рисунке.</p> -<pre class="brush: python notranslate">class Meta: +<pre class="brush: python">class Meta: ordering = ["-my_field_name"] ...</pre> @@ -156,13 +156,13 @@ class MyModelName(models.Model): <p>Например, если мы решили сортировать книги по умолчанию:</p> -<pre class="brush: python notranslate">ordering = ["title", "-pubdate"]</pre> +<pre class="brush: python">ordering = ["title", "-pubdate"]</pre> <p>Книги будут отсортированы по алфавиту по названию, от A-Z, а затем по дате публикации внутри каждого названия, от самого нового до самого старого.</p> <p>Другим распространённым атрибутом является verbose_name, подробное имя для класса в единственной и множественной форме:</p> -<pre class="brush: python notranslate">verbose_name = "BetterName"</pre> +<pre class="brush: python">verbose_name = "BetterName"</pre> <p>Другие полезные атрибуты позволяют создавать и применять новые «разрешения доступа» для модели (разрешения по умолчанию применяются автоматически), разрешить упорядочение на основе другого поля или объявить, что класс является «абстрактным» (базовый класс, для которого вы не можете создавать записи, и вместо этого будет создан для создания других моделей). Многие другие параметры метаданных управляют тем, какая база данных должна использоваться для модели и как хранятся данные (это действительно полезно, если вам нужно сопоставить модель с существующей базой данных). Полный список опций метаданных доступен здесь: <a href="https://docs.djangoproject.com/en/2.2/ref/models/options/#model-meta-options">Model metadata options</a> (Django документация).</p> @@ -170,12 +170,12 @@ class MyModelName(models.Model): <p>Модель также может иметь методы. Минимально в каждой модели вы должны определить стандартный метод класса для Python __str __ (), чтобы вернуть удобочитаемую строку для каждого объекта. Эта строка используется для представления отдельных записей на сайте администрирования (и в любом другом месте, где вам нужно обратиться к экземпляру модели). Часто это возвращает поле названия или имени из модели.</p> -<pre class="brush: python notranslate">def __str__(self): +<pre class="brush: python">def __str__(self): return self.field_name</pre> <p>Другим распространённым методом включения в модели Django является get_absolute_url (), который возвращает URL-адрес для отображения отдельных записей модели на веб-сайте (если вы определяете этот метод, тогда Django автоматически добавит кнопку «Просмотр на сайте» на экранах редактирования записей модели на сайте администратора). Типичный шаблон для get_absolute_url () показан ниже.</p> -<pre class="brush: python notranslate">def get_absolute_url(self): +<pre class="brush: python">def get_absolute_url(self): """ Returns the url to access a particular instance of the model. """ @@ -198,7 +198,7 @@ class MyModelName(models.Model): <p>Чтобы создать запись, вы можете определить экземпляр модели, а затем вызвать метод save ().</p> -<pre class="brush: python notranslate"># Create a new record using the model's constructor. +<pre class="brush: python"># Create a new record using the model's constructor. a_record = MyModelName(my_field_name="Instance #1") # Save the object into the database. @@ -211,7 +211,7 @@ a_record.save() <p>Вы можете получить доступ к полям в этой новой записи с использованием синтаксиса точек и изменить значения. Вы должны вызвать save (), чтобы сохранить изменённые значения в базе данных.</p> -<pre class="brush: python notranslate"># Access model field values using Python attributes. +<pre class="brush: python"># Access model field values using Python attributes. print(a_record.id) #should return 1 for the first record. print(a_record.my_field_name) # should print 'Instance #1' @@ -229,12 +229,12 @@ a_record.save()</pre> <p>Мы можем получить все записи для модели как объект QuerySet, используя <code>objects.all()</code>. QuerySet - это итерируемый объект, означающий, что он содержит несколько объектов, которые мы можем перебирать / прокручивать.</p> -<pre class="brush: python notranslate">all_books = Book.objects.all() +<pre class="brush: python">all_books = Book.objects.all() </pre> <p>Метод <code>filter()</code> Django позволяет отфильтровать возвращаемый <code>QuerySet</code> для соответствия указанному текстовому или числовому полю по конкретным критериям. Например, чтобы отфильтровать книги, содержащие слово «wild» («дикие») в заголовке, а затем подсчитать их, мы могли бы сделать следующее.</p> -<pre class="brush: python notranslate">wild_books = Book.objects.filter(title__contains='wild') +<pre class="brush: python">wild_books = Book.objects.filter(title__contains='wild') number_wild_books = Book.objects.filter(title__contains='wild').count() </pre> @@ -242,7 +242,7 @@ number_wild_books = Book.objects.filter(title__contains='wild').count() <p>В некоторых случаях вам нужно будет фильтровать поле, которое определяет отношение «один ко многим» к другой модели (например, <code>ForeignKey</code>). В этом случае вы можете «индексировать» поля в связанной модели с дополнительными двойными подчёркиваниями. Так, например, чтобы фильтровать книги с определённым жанровым рисунком, вам нужно будет указывать имя в поле жанра, как показано ниже:</p> -<pre class="brush: python notranslate">books_containing_genre = Book.objects.filter(genre<strong>__</strong>name<strong>__</strong>icontains='fiction') # Will match on: Fiction, Science fiction, non-fiction etc. +<pre class="brush: python">books_containing_genre = Book.objects.filter(genre<strong>__</strong>name<strong>__</strong>icontains='fiction') # Will match on: Fiction, Science fiction, non-fiction etc. </pre> <div class="note"> @@ -255,7 +255,7 @@ number_wild_books = Book.objects.filter(title__contains='wild').count() <p>В этом разделе мы начнём определять модели для библиотеки. Откройте <em>models.py (в / locallibrary / catalog /)</em>. Шаблон в верхней части страницы импортирует модуль моделей, который содержит базовый класс модели <code>models.Model</code>, от которого наследуются наши модели.</p> -<pre class="brush: python notranslate">from django.db import models +<pre class="brush: python">from django.db import models # Create your models here.</pre> @@ -263,7 +263,7 @@ number_wild_books = Book.objects.filter(title__contains='wild').count() <p>Скопируйте приведённый ниже код модели <code>Genre </code>и вставьте его в нижнюю часть вашего файла <code>models.py</code>. Эта модель используется для хранения информации о категории книг - например, будь то художественная или документальная, роман или военно-историческая и т. д. Как уже упоминалось выше, мы создали жанр как модель, а не как свободный текст или список выбора, чтобы возможные значения могли управляться через базу данных, а не были закодированными.</p> -<pre class="brush: python notranslate">class Genre(models.Model): +<pre class="brush: python">class Genre(models.Model): """ Model representing a book genre (e.g. Science Fiction, Non Fiction). """ @@ -281,7 +281,7 @@ number_wild_books = Book.objects.filter(title__contains='wild').count() <p>Скопируйте модель книги ниже и снова вставьте её в нижнюю часть файла. Модель книги представляет всю информацию о доступной книге в общем смысле, но не конкретный физический «экземпляр» или «копию» для временного использования. Модель использует CharField для представления названия книги и isbn (обратите внимание, как isbn указывает свой ярлык как «ISBN», используя первый неименованный параметр, поскольку в противном случае ярлык по умолчанию был бы «Isbn»). Модель использует TextField для summary, потому что этот текст, возможно, должен быть очень длинным.</p> -<pre class="brush: python notranslate">from django.urls import reverse #Used to generate URLs by reversing the URL patterns +<pre class="brush: python">from django.urls import reverse #Used to generate URLs by reversing the URL patterns class Book(models.Model): """ @@ -326,7 +326,7 @@ class Book(models.Model): <li>CharField, для представления данных (конкретного выпуска) о книге.</li> </ul> -<pre class="brush: python notranslate">import uuid # Required for unique book instances +<pre class="brush: python">import uuid # Required for unique book instances class BookInstance(models.Model): """ @@ -382,7 +382,7 @@ class BookInstance(models.Model): <p>Теперь все поля/методы должны быть знакомы. Модель определяет автора как имя, фамилию, дату рождения и (необязательную) дату смерти. Он указывает, что по умолчанию __str __ () возвращает имя в фамилии, порядковый номер первого имени. Метод get_absolute_url () отменяет сопоставление URL-адреса автора с целью получения URL-адреса для отображения отдельного автора.</p> -<pre class="brush: python notranslate">class Author(models.Model): +<pre class="brush: python">class Author(models.Model): """ Model representing an author. """ @@ -409,7 +409,7 @@ class BookInstance(models.Model): <p>Теперь все ваши модели созданы. Теперь переустановите миграцию базы данных, чтобы добавить их в свою базу данных.</p> -<pre class="notranslate"><code>python3 manage.py makemigrations +<pre><code>python3 manage.py makemigrations python3 manage.py migrate</code></pre> <h2 id="Языковая_модель_-_вызов">Языковая модель - вызов</h2> diff --git a/files/ru/learn/server-side/express_nodejs/development_environment/index.html b/files/ru/learn/server-side/express_nodejs/development_environment/index.html index c0c188f731..626090c6a0 100644 --- a/files/ru/learn/server-side/express_nodejs/development_environment/index.html +++ b/files/ru/learn/server-side/express_nodejs/development_environment/index.html @@ -85,7 +85,7 @@ translation_of: Learn/Server-side/Express_Nodejs/development_environment <p><span class="tlid-translation translation" lang="ru"><span title="">Самый простой способ установить последнюю версию LTS Node 6.x - это использовать</span></span> <a href="https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions">package manager</a> <span class="tlid-translation translation" lang="ru"><span title="">чтобы получить его из репозитория бинарных дистрибутивов Ubuntu.</span> <span title="">Это можно сделать очень просто, выполнив следующие две команды на вашем терминале:</span></span></p> -<pre class="brush: bash notranslate"><code>curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - +<pre class="brush: bash"><code>curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs</code> </pre> @@ -100,12 +100,12 @@ sudo apt-get install -y nodejs</code> <p><span class="tlid-translation translation" lang="ru"><span title="">Самый простой способ проверить, установлен ли этот узел, - это запустить команду «версия» в своём терминале / командной строке и проверить, что возвращается строка версии:</span></span></p> -<pre class="brush: bash notranslate">>node -v +<pre class="brush: bash">>node -v v8.11.3</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Менеджер пакетов Nodejs NPM также должен быть установлен и может быть протестирован таким же образом:</span></span></p> -<pre class="brush: bash notranslate">>npm -v +<pre class="brush: bash">>npm -v 5.8.0</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">В качестве немного более захватывающего теста давайте создадим очень простой сервер «чистого узла», который просто печатает «Hello World» в браузере, когда вы посещаете правильный URL в вашем браузере:</span></span></p> @@ -113,7 +113,7 @@ v8.11.3</pre> <ol> <li><span class="tlid-translation translation" lang="ru"><span title="">Скопируйте следующий текст в файл с именем hellonode.js.</span> <span title="">Здесь используются чистые функции Node (ничего из Express) и некоторый синтаксис ES6:</span></span> - <pre class="brush: js notranslate">//Загрузка модуля HTTP + <pre class="brush: js">//Загрузка модуля HTTP const http = require("http"); <code>const hostname = '127.0.0.1'; const port = 3000; @@ -141,7 +141,7 @@ server.listen(port, hostname, () => { </div> </li> <li><span class="tlid-translation translation" lang="ru"><span title="">Запустите сервер, перейдя в тот же каталог, что и ваш файл hellonode.js в командной строке, и вызвав узел вместе с именем скрипта, например так:</span></span> - <pre class="brush: bash notranslate">>node hellonode.js + <pre class="brush: bash">>node hellonode.js Server running at http://127.0.0.1:3000/ </pre> </li> @@ -169,15 +169,15 @@ Server running at http://127.0.0.1:3000/ <ol> <li><span class="tlid-translation translation" lang="ru"><span title="">Сначала создайте каталог для вашего нового приложения и перейдите в него:</span></span> - <pre class="brush: bash notranslate">mkdir myapp + <pre class="brush: bash">mkdir myapp cd myapp</pre> </li> <li><span class="tlid-translation translation" lang="ru"><span title="">Используйте команду npm init для создания файла package.json для вашего приложения.</span> <span title="">Эта команда запрашивает у вас несколько вещей, включая имя и версию вашего приложения, а также имя исходного файла точки входа (по умолчанию это index.js).</span> <span title="">Сейчас просто примите значения по умолчанию:</span></span> - <pre class="brush: bash notranslate">npm init</pre> + <pre class="brush: bash">npm init</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Если вы отобразите файл package.json (cat package.json), вы увидите принятые по умолчанию значения, заканчивающиеся лицензией.</span></span></p> - <pre class="brush: json notranslate">{ + <pre class="brush: json">{ "name": "myapp", "version": "1.0.0", "description": "", @@ -192,11 +192,11 @@ cd myapp</pre> </li> <li><span class="tlid-translation translation" lang="ru"><span title="">Теперь установите Express в каталог myapp и сохраните его в списке зависимостей вашего файла package.json</span></span></li> <li> - <pre class="brush: bash notranslate">npm install express --save</pre> + <pre class="brush: bash">npm install express --save</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Раздел зависимостей вашего package.json теперь появится в конце файла package.json и будет содержать Express.</span></span></p> - <pre class="brush: json notranslate">{ + <pre class="brush: json">{ "name": "myapp", "version": "1.0.0", "description": "", @@ -213,7 +213,7 @@ cd myapp</pre> </pre> </li> <li><span class="tlid-translation translation" lang="ru"><span title="">Для использования библиотеки вы вызываете функцию require (), как показано ниже в вашем файле index.js.</span></span> - <pre class="notranslate"><code><strong>const express = require('express')</strong> + <pre><code><strong>const express = require('express')</strong> const app = express(); app.get('/', (req, res) => { @@ -230,7 +230,7 @@ app.listen(</code>8000<code>, () => { <span class="tlid-translation translation" lang="ru"><span title="">Создайте файл с именем index.js в корне каталога приложения «myapp» и передайте ему содержимое, показанное выше.</span></span></p> </li> <li><span class="tlid-translation translation" lang="ru"><span title="">Вы можете запустить сервер, вызвав узел с помощью скрипта в командной строке:</span></span> - <pre class="brush: bash notranslate">>node index.js + <pre class="brush: bash">>node index.js Example app listening on port 8000 </pre> </li> @@ -241,11 +241,11 @@ Example app listening on port 8000 <p><span class="tlid-translation translation" lang="ru"><span title="">Если зависимость используется только во время разработки, вы должны вместо этого сохранить её как «зависимость разработки» (чтобы пользователям вашего пакета не приходилось устанавливать её в производстве).</span> <span title="">Например, чтобы использовать популярный инструмент JavaScript Linting eslint, вы должны вызвать NPM, как показано ниже:</span></span></p> -<pre class="brush: bash notranslate"><code>npm install eslint --save-dev</code></pre> +<pre class="brush: bash"><code>npm install eslint --save-dev</code></pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Следующая запись будет добавлена в package.json вашего приложения:</span></span></p> -<pre class="brush: js notranslate"> "devDependencies": { +<pre class="brush: js"> "devDependencies": { "eslint": "^4.12.1" } </pre> @@ -264,7 +264,7 @@ Example app listening on port 8000 <p><span class="tlid-translation translation" lang="ru"><span title="">Например, чтобы определить скрипт для запуска зависимости разработки eslint, которую мы указали в предыдущем разделе, мы могли бы добавить следующий блок скрипта в наш файл package.json (при условии, что наш источник приложения находится в папке / src / js):</span></span></p> -<pre class="brush: js notranslate">"scripts": { +<pre class="brush: js">"scripts": { ... "lint": "eslint src/js" ... @@ -275,7 +275,7 @@ Example app listening on port 8000 <p><span class="tlid-translation translation" lang="ru"><span title="">Затем мы сможем запустить eslint с помощью NPM, вызвав:</span></span></p> -<pre class="brush: bash notranslate"><code>npm run-script lint +<pre class="brush: bash"><code>npm run-script lint # OR (using the alias) npm run lint</code> </pre> @@ -286,16 +286,16 @@ npm run lint</code> <p><span class="tlid-translation translation" lang="ru"><span title="">Инструмент Express Application Generator создаёт «скелет» приложения Express.</span> <span title="">Установите генератор, используя NPM, как показано (флаг -g устанавливает инструмент глобально, чтобы вы могли вызывать его из любого места):</span></span></p> -<pre class="notranslate"><code>npm install express-generator -g</code></pre> +<pre><code>npm install express-generator -g</code></pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Чтобы создать приложение Express с именем «helloworld» с настройками по умолчанию, перейдите туда, где вы хотите его создать, и запустите приложение, как показано ниже:</span></span></p> -<pre class="brush: bash notranslate">express helloworld</pre> +<pre class="brush: bash">express helloworld</pre> <div class="note"> <p><strong>Замечание:</strong> <span class="tlid-translation translation" lang="ru"><span title="">Вы также можете указать библиотеку шаблонов для использования и ряд других настроек.</span> <span title="">Используйте команду help, чтобы увидеть все параметры:</span></span></p> -<pre class="brush: bash notranslate">express --help +<pre class="brush: bash">express --help </pre> </div> @@ -304,7 +304,7 @@ npm run lint</code> <div class="note"> <p><span class="tlid-translation translation" lang="ru"><span title="">Новое приложение будет иметь файл package.json в своём корневом каталоге.</span> <span title="">Вы можете открыть это, чтобы увидеть, какие зависимости установлены, включая Express и библиотеку шаблонов Jade:</span></span></p> -<pre class="brush: js notranslate">{ +<pre class="brush: js">{ "name": "helloworld", "version": "0.0.0", "private": true, @@ -325,13 +325,13 @@ npm run lint</code> <p><span class="tlid-translation translation" lang="ru"><span title="">Установите все зависимости для приложения helloworld, используя NPM, как показано ниже:</span></span></p> -<pre class="brush: bash notranslate">cd helloworld +<pre class="brush: bash">cd helloworld npm install </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Затем запустите приложение (команды немного отличаются для Windows и Linux / macOS), как показано ниже:</span></span></p> -<pre class="brush: bash notranslate"># Run the helloworld on Windows with Command Prompt +<pre class="brush: bash"># Run the helloworld on Windows with Command Prompt SET DEBUG=helloworld:* & npm start # Run the helloworld on Windows with PowerShell @@ -343,7 +343,7 @@ DEBUG=helloworld:* npm start <p><span class="tlid-translation translation" lang="ru"><span title="">Команда DEBUG создаёт полезное ведение журнала, что приводит к выводу, подобному показанному ниже.</span></span></p> -<pre class="brush: bash notranslate">>SET DEBUG=helloworld:* & npm start +<pre class="brush: bash">>SET DEBUG=helloworld:* & npm start > helloworld@0.0.0 start D:\Github\expresstests\helloworld > node ./bin/www diff --git a/files/ru/learn/server-side/express_nodejs/displaying_data/locallibrary_base_template/index.html b/files/ru/learn/server-side/express_nodejs/displaying_data/locallibrary_base_template/index.html index c8b39b2872..830c895bc8 100644 --- a/files/ru/learn/server-side/express_nodejs/displaying_data/locallibrary_base_template/index.html +++ b/files/ru/learn/server-side/express_nodejs/displaying_data/locallibrary_base_template/index.html @@ -7,7 +7,7 @@ translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_ba <p>Откройте файл <strong>/views/layout.pug </strong>и замените его содержимое следующим.</p> -<pre class="brush: html line-numbers language-html notranslate"><code class="language-html">doctype html +<pre class="brush: html line-numbers language-html"><code class="language-html">doctype html html(lang='en') head title= title @@ -53,7 +53,7 @@ html(lang='en') <p>Базовый шаблон также ссылается на локальный файл стилей (<strong>style.css</strong>), что обеспечивает дополнительное управление внешним видом. Откройте <strong>/public/stylesheets/style.css</strong> и замените его содержимое таким текстом:</p> -<pre class="brush: css line-numbers language-css notranslate"><code class="language-css"><span class="selector token"><span class="class token">.sidebar-nav</span> </span><span class="punctuation token">{</span> +<pre class="brush: css line-numbers language-css"><code class="language-css"><span class="selector token"><span class="class token">.sidebar-nav</span> </span><span class="punctuation token">{</span> <span class="property token">margin-top</span><span class="punctuation token">:</span> <span class="number token">20</span>px<span class="punctuation token">;</span> <span class="property token">padding</span><span class="punctuation token">:</span> <span class="number token">0</span><span class="punctuation token">;</span> <span class="property token">list-style</span><span class="punctuation token">:</span> none<span class="punctuation token">;</span> diff --git a/files/ru/learn/server-side/express_nodejs/forms/index.html b/files/ru/learn/server-side/express_nodejs/forms/index.html index 1a6208f065..910f6a53ed 100644 --- a/files/ru/learn/server-side/express_nodejs/forms/index.html +++ b/files/ru/learn/server-side/express_nodejs/forms/index.html @@ -46,7 +46,7 @@ translation_of: Learn/Server-side/Express_Nodejs/forms <p>Определённые в HTML формы собираются внутри тэга <code><form>...</form></code>, содержащего хотя ы один элемент <code>input</code> с <code>type="submit"</code>.</p> -<pre class="brush: html notranslate"><form action="/team_name_url/" method="post"> +<pre class="brush: html"><form action="/team_name_url/" method="post"> <label for="team_name">Enter name: </label> <input id="team_name" type="text" name="name_field" value="Default name for team."> <input type="submit" value="OK"> @@ -108,7 +108,7 @@ translation_of: Learn/Server-side/Express_Nodejs/forms <p>Установите модуль, выполнив следующую команду в корне проекта</p> -<pre class="brush: bash notranslate">npm install express-validator +<pre class="brush: bash">npm install express-validator </pre> <h4 id="Использование_express-validator">Использование express-validator</h4> @@ -119,7 +119,7 @@ translation_of: Learn/Server-side/Express_Nodejs/forms <p>Для того, чтобы использовать валидатор в наших контроллерах, мы должны требовать функции, которые мы хотим использовать из модулей <strong>'express-validator/check</strong>' и <strong>'express-validator/filter</strong>', как показано ниже:</p> -<pre class="brush: js notranslate">const { body,validationResult } = require('express-validator/check'); +<pre class="brush: js">const { body,validationResult } = require('express-validator/check'); const { sanitizeBody } = require('express-validator/filter'); </pre> @@ -130,12 +130,12 @@ const { sanitizeBody } = require('express-validator/filter'); <ul> <li><code><a href="https://github.com/ctavan/express-validator#bodyfields-message">body(fields[, message])</a></code>: Задаёт набор полей в теле запроса (параметр <code>POST</code>) для проверки, а также необязательное сообщение об ошибке, которое может отображаться в случае сбоя тестов. Критерии проверки последовательно связаны с методом <code>body()</code>. Например, первая проверка ниже проверяет, что поле" имя "не пустое и задаёт сообщение об ошибке" пустое имя", если оно не пустое. Второй тест проверяет, что поле age является допустимой датой, и с помощью optional() указывает, что пустые и пустые строки не пройдут проверку. - <pre class="brush: js notranslate">body('name', 'Empty name').isLength({ min: 1 }), + <pre class="brush: js">body('name', 'Empty name').isLength({ min: 1 }), body('age', 'Invalid age').optional({ checkFalsy: true }).isISO8601(), </pre> Можно также последовательно подключить различные валидаторы и добавить сообщения, отображаемые при выполнении предыдущих валидаторов.</li> <li> - <pre class="brush: js notranslate">body('name').isLength({ min: 1 }).trim().withMessage('Name empty.') + <pre class="brush: js">body('name').isLength({ min: 1 }).trim().withMessage('Name empty.') .isAlpha().withMessage('Name must be alphabet letters.'), </pre> @@ -144,11 +144,11 @@ body('age', 'Invalid age').optional({ checkFalsy: true }).isISO8601(), </div> </li> <li><code><a href="https://github.com/ctavan/express-validator#sanitizebodyfields">sanitizeBody(fields)</a></code>: Задаёт поле тела для очистки. затем операции очистки последовательно соединяются с этим методом. Например, операция очистки <code>escape()</code>, описанная ниже, удаляет символы HTML из переменной name, которые могут использоваться в атаках сценариев между сайтами JavaScript. - <pre class="brush: js notranslate">sanitizeBody('name').trim().escape(), + <pre class="brush: js">sanitizeBody('name').trim().escape(), sanitizeBody('date').toDate(),</pre> </li> <li><code><a href="https://github.com/ctavan/express-validator#validationresultreq">validationResult(req)</a></code>: Запускает проверку, делая ошибки доступными в виде объекта результата проверки. Это вызывается в отдельном обратном вызове, как показано ниже: - <pre class="brush: js notranslate">(req, res, next) => { + <pre class="brush: js">(req, res, next) => { // Extract the validation errors from a request. const errors = validationResult(req); @@ -193,7 +193,7 @@ sanitizeBody('date').toDate(),</pre> <p>Мы уже создали маршруты для всех страниц создания нашей модели в <strong>/routes/catalog.js</strong> (in a <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes">previous tutorial</a>). Например, жанровые маршруты показаны ниже:</p> -<pre class="brush: js notranslate">// GET request for creating a Genre. NOTE This must come before route that displays Genre (uses id). +<pre class="brush: js">// GET request for creating a Genre. NOTE This must come before route that displays Genre (uses id). router.get('/genre/create', genre_controller.genre_create_get); // POST request for creating Genre. diff --git a/files/ru/learn/server-side/express_nodejs/introduction/index.html b/files/ru/learn/server-side/express_nodejs/introduction/index.html index 881a3c70d6..cbcafaa64a 100644 --- a/files/ru/learn/server-side/express_nodejs/introduction/index.html +++ b/files/ru/learn/server-side/express_nodejs/introduction/index.html @@ -46,13 +46,13 @@ translation_of: Learn/Server-side/Express_Nodejs/Introduction <li>Создайте папку, куда вы хотите сохранить программу, к примеру <code>test-node</code> и перейдите в неё с помощью следующей команды:</li> </ol> -<pre class="notranslate"><code>cd test-node</code></pre> +<pre><code>cd test-node</code></pre> <ol start="3"> <li>Используя любимый текстовый редактор, создайте файл <code>hello.js</code> и вставьте в него код:</li> </ol> -<pre class="brush: js notranslate">// Загружаем HTTP модуль +<pre class="brush: js">// Загружаем HTTP модуль const http = require("http"); const hostname = "127.0.0.1"; @@ -79,7 +79,7 @@ server.listen(port, hostname, () => { <li>Вернитесь в терминал и выполните следующую команду:</li> </ol> -<pre class="notranslate"><code>node hello.js</code></pre> +<pre><code>node hello.js</code></pre> <p>В итоге, перейдите по ссылке <code>http://localhost:8000</code> в вашем браузере; вы должны увидеть текст "<strong>Hello World</strong>" в верху слева на чистой странице.</p> @@ -144,7 +144,7 @@ server.listen(port, hostname, () => { <p><span class="tlid-translation translation" lang="ru"><span title="">Совет: Если у вас уже установлены Node и Express (или если вы устанавливаете их, как показано в следующей статье), вы можете сохранить этот код в файле с именем app.js и запустить его в командной строке, вызвав узел app.js.</span> <span title="">отражения</span><span title="">)</span><span title="">.</span></span></p> </div> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var app = express(); <strong>app.get('/', function(req, res) { @@ -168,7 +168,7 @@ app.listen(3000, function() { <br> <span title="">Приведённый ниже код показывает, как мы импортируем модуль по имени, используя в качестве примера платформу Express.</span> <span title="">Сначала мы вызываем функцию require (), определяя имя модуля в виде строки («express») и вызывая возвращённый объект для создания приложения Express.</span> <span title="">Затем мы можем получить доступ к свойствам и функциям объекта приложения.</span></span></p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var app = express(); </pre> @@ -180,13 +180,13 @@ var app = express(); <p><span class="tlid-translation translation" lang="ru"><span title="">Чтобы сделать объекты доступными вне модуля, вам просто нужно назначить их объекту экспорта.</span> <span title="">Например, модуль square.js ниже представляет собой файл, который экспортирует методы area () и perimeter ():</span></span></p> -<pre class="brush: js notranslate">exports.area = function(width) { return width * width; }; +<pre class="brush: js">exports.area = function(width) { return width * width; }; exports.perimeter = function(width) { return 4 * width; }; </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Мы можем импортировать этот модуль, используя require (), а затем вызвать экспортированные методы, как показано:</span></span></p> -<pre class="brush: js notranslate">var square = require('./square'); // Here we require() the name of the file without the (optional) .js file extension +<pre class="brush: js">var square = require('./square'); // Here we require() the name of the file without the (optional) .js file extension console.log('The area of a square with a width of 4 is ' + square.area(4));</pre> <div class="note"> @@ -195,7 +195,7 @@ console.log('The area of a square with a width of 4 is ' + square.area(4));</pre <p><span class="tlid-translation translation" lang="ru"><span title="">Если вы хотите экспортировать полный объект в одном назначении, а не создавать его по одному свойству за раз, назначьте его для module.exports, как показано ниже (вы также можете сделать это, чтобы сделать корень объекта экспорта конструктором или другой функцией)</span> <span title="">:</span></span></p> -<pre class="brush: js notranslate">module.exports = { +<pre class="brush: js">module.exports = { area: function(width) { return width * width; }, @@ -212,13 +212,13 @@ console.log('The area of a square with a width of 4 is ' + square.area(4));</pre <p><span class="tlid-translation translation" lang="ru"><span title="">Код JavaScript часто использует асинхронные, а не синхронные API для операций, выполнение которых может занять некоторое время.</span> <span title="">Синхронный API - это тот, в котором каждая операция должна завершиться до начала следующей операции.</span> <span title="">Например, следующие функции журнала являются синхронными и выводят текст на консоль по порядку (первый, второй).</span></span></p> -<pre class="brush: js notranslate">console.log('First'); +<pre class="brush: js">console.log('First'); console.log('Second'); </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">В отличие от этого, асинхронный API - это тот, в котором API начнёт операцию и сразу же вернётся (до завершения операции).</span> <span title="">После завершения операции API будет использовать некоторый механизм для выполнения дополнительных операций.</span> <span title="">Например, приведённый ниже код выведет «Second, First», потому что хотя метод setTimeout () вызывается первым и возвращается немедленно, операция не завершается в течение нескольких секунд.</span></span></p> -<pre class="brush: js notranslate">setTimeout(function() { +<pre class="brush: js">setTimeout(function() { console.log('First'); }, 3000); console.log('Second'); @@ -240,7 +240,7 @@ console.log('Second'); <p><span class="tlid-translation translation" lang="ru"><span title="">В нашем примере Hello World Express (см. Выше) мы определили функцию обработчика маршрута (колбэка) для HTTP-запросов GET к корню сайта ('/').</span></span></p> -<pre class="brush: js notranslate">app.<strong>get</strong>('/', function(req, res) { +<pre class="brush: js">app.<strong>get</strong>('/', function(req, res) { res.send('Hello World!'); }); </pre> @@ -255,7 +255,7 @@ console.log('Second'); <p><span class="tlid-translation translation" lang="ru"><span title="">Существует специальный метод маршрутизации app.all (), который будет вызываться в ответ на любой метод HTTP.</span> <span title="">Это используется для загрузки функций промежуточного программного обеспечения по определённому пути для всех методов запроса.</span> <span title="">В следующем примере (из документации Express) показан обработчик, который будет выполняться для запросов к / secret независимо от используемого глагола HTTP (при условии, что он поддерживается модулем http).</span></span></p> -<pre class="brush: js notranslate">app.all('/secret', function(req, res, next) { +<pre class="brush: js">app.all('/secret', function(req, res, next) { console.log('Accessing the secret section ...'); next(); // pass control to the next handler });</pre> @@ -264,7 +264,7 @@ console.log('Second'); <br> <span title="">Часто полезно группировать обработчики маршрутов для определённой части сайта и получать к ним доступ с помощью общего префикса маршрута (например, сайт с вики может иметь все связанные с вики маршруты в одном файле и иметь к ним доступ с префиксом маршрута</span> <span title="">из / вики /).</span> <span title="">В Express это достигается с помощью объекта express.Router.</span> <span title="">Например, мы можем создать наш вики-маршрут в модуле с именем wiki.js, а затем экспортировать объект Router, как показано ниже:</span></span></p> -<pre class="brush: js notranslate">// wiki.js - Wiki route module +<pre class="brush: js">// wiki.js - Wiki route module var express = require('express'); var router = express.Router(); @@ -288,7 +288,7 @@ module.exports = router; <p><span class="tlid-translation translation" lang="ru"><span title="">Чтобы использовать маршрутизатор в нашем главном файле приложения, нам потребуется () модуль route (wiki.js), а затем вызовите use () в приложении Express, чтобы добавить маршрутизатор в путь обработки промежуточного программного обеспечения.</span> <span title="">Эти два маршрута будут доступны из / wiki / и / wiki / about /.</span></span></p> -<pre class="brush: js notranslate">var wiki = require('./wiki.js'); +<pre class="brush: js">var wiki = require('./wiki.js'); // ... app.use('/wiki', wiki);</pre> @@ -306,12 +306,12 @@ app.use('/wiki', wiki);</pre> <br> <span title="">Для использования стороннего промежуточного программного обеспечения сначала необходимо установить его в своё приложение с помощью NPM.</span> <span title="">Например, чтобы установить промежуточное программное обеспечение средства регистрации HTTP-запросов morgan, вы должны сделать следующее:</span></span></p> -<pre class="brush: bash notranslate"><code>$ npm install morgan +<pre class="brush: bash"><code>$ npm install morgan </code></pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Затем вы можете вызвать use () для объекта приложения Express, чтобы добавить промежуточное программное обеспечение в стек:</span></span></p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); <strong>var logger = require('morgan');</strong> var app = express(); <strong>app.use(logger('dev'));</strong> @@ -327,7 +327,7 @@ var app = express(); <br> <span title="">В приведённом ниже примере показано, как можно добавить функцию промежуточного программного обеспечения, используя оба метода, а также с / без маршрута.</span></span></p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var app = express(); // An example middleware function @@ -357,12 +357,12 @@ app.listen(3000);</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете использовать промежуточное программное обеспечение express.static для обслуживания статических файлов, включая ваши изображения, CSS и JavaScript (static () - единственная функция промежуточного программного обеспечения, которая фактически является частью Express).</span> <span title="">Например, вы должны использовать строку ниже для обслуживания изображений, файлов CSS и файлов JavaScript из каталога с именем public на том же уровне, где вы вызываете узел:</span></span></p> -<pre class="brush: js notranslate">app.use(express.static('public')); +<pre class="brush: js">app.use(express.static('public')); </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Любые файлы в публичном каталоге обслуживаются путём добавления их имени файла (относительно базового «публичного» каталога) к базовому URL.</span> <span title="">Так, например:</span></span></p> -<pre class="notranslate"><code>http://localhost:3000/images/dog.jpg +<pre><code>http://localhost:3000/images/dog.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js http://localhost:3000/about.html @@ -370,18 +370,18 @@ http://localhost:3000/about.html <p><span class="tlid-translation translation" lang="ru"><span title="">Вы можете вызывать static () несколько раз для обслуживания нескольких каталогов.</span> <span title="">Если файл не может быть найден одной функцией промежуточного программного обеспечения, он будет просто передан последующему промежуточному программному обеспечению (порядок вызова промежуточного программного обеспечения основан на вашем порядке объявления).</span></span></p> -<pre class="brush: js notranslate">app.use(express.static('public')); +<pre class="brush: js">app.use(express.static('public')); app.use(express.static('media')); </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Вы также можете создать виртуальный префикс для ваших статических URL-адресов, вместо добавления файлов к базовому URL-адресу.</span> <span title="">Например, здесь мы указываем путь монтирования, чтобы файлы загружались с префиксом "/ media":</span></span></p> -<pre class="brush: js notranslate">app.use('/media', express.static('public')); +<pre class="brush: js">app.use('/media', express.static('public')); </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Теперь вы можете загружать файлы, находящиеся в публичном каталоге, из префикса / media path.</span></span></p> -<pre class="notranslate"><code>http://localhost:3000/media/images/dog.jpg +<pre><code>http://localhost:3000/media/images/dog.jpg http://localhost:3000/media/video/cat.mp4 http://localhost:3000/media/cry.mp3</code> </pre> @@ -392,7 +392,7 @@ http://localhost:3000/media/cry.mp3</code> <p><span class="tlid-translation translation" lang="ru"><span title="">Ошибки обрабатываются одной или несколькими специальными функциями промежуточного программного обеспечения, которые имеют четыре аргумента вместо обычных трёх: (err, req, res, next).</span> <span title="">Например:</span></span></p> -<pre class="brush: js notranslate">app.use(function(err, req, res, next) { +<pre class="brush: js">app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); @@ -418,12 +418,12 @@ http://localhost:3000/media/cry.mp3</code> <br> <span title="">Чтобы использовать их, вы должны сначала установить драйвер базы данных, используя NPM.</span> <span title="">Например, чтобы установить драйвер для популярной NoSQL MongoDB, вы должны использовать команду:</span></span></p> -<pre class="brush: bash notranslate"><code>$ npm install mongodb +<pre class="brush: bash"><code>$ npm install mongodb </code></pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Сама база данных может быть установлена локально или на облачном сервере.</span> <span title="">В вашем экспресс-коде вам требуется драйвер, подключиться к базе данных, а затем выполнить операции создания, чтения, обновления и удаления (CRUD).</span> <span title="">Пример ниже (из документации Express) показывает, как вы можете найти записи «млекопитающих», используя MongoDB.</span></span></p> -<pre class="brush: js notranslate">var MongoClient = require('mongodb').MongoClient; +<pre class="brush: js">var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) { if (err) throw err; @@ -445,7 +445,7 @@ MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) { <br> <span title="">В своём коде настроек приложения вы задаёте механизм шаблонов для использования и место, где Express должен искать шаблоны, используя настройки «views» и «engine», как показано ниже (вам также нужно будет установить пакет, содержащий вашу библиотеку шаблонов).</span> <span title="">!</span><span title="">)</span></span></p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var app = express(); // Set directory to contain the templates ('views') @@ -457,7 +457,7 @@ app.set('view engine', 'some_template_engine_name'); <p><span class="tlid-translation translation" lang="ru"><span title="">Внешний вид шаблона будет зависеть от того, какой движок вы используете.</span> <span title="">Предполагая, что у вас есть файл шаблона с именем «index. <Template_extension>», который содержит заполнители для переменных данных с именами «title» и «message», вы должны вызвать Response.render () в функции обработчика маршрута для создания и отправки ответа HTML.</span> <span title="">:</span></span></p> -<pre class="brush: js notranslate">app.get('/', function(req, res) { +<pre class="brush: js">app.get('/', function(req, res) { res.render('index', { title: 'About dogs', message: 'Dogs rock!' }); });</pre> diff --git a/files/ru/learn/server-side/express_nodejs/skeleton_website/index.html b/files/ru/learn/server-side/express_nodejs/skeleton_website/index.html index f1c993e54d..90ec704439 100644 --- a/files/ru/learn/server-side/express_nodejs/skeleton_website/index.html +++ b/files/ru/learn/server-side/express_nodejs/skeleton_website/index.html @@ -36,12 +36,12 @@ translation_of: Learn/Server-side/Express_Nodejs/skeleton_website <p>Вы уже должны были установить <code>express-generator</code>, читая статью <a>установка среды разработки Node</a>. Напомним, что генератор установлен с помощью менеджера пакетов NPM, при выполнении команды:</p> -<pre class="brush: bash notranslate"><code>npm install express-generator -g</code> +<pre class="brush: bash"><code>npm install express-generator -g</code> </pre> <p><code>E</code><code>xpress-generator </code>имеет ряд параметров, которые можно увидеть, выполнив команду express --help (или express -h):</p> -<pre class="brush: bash notranslate">> express --help +<pre class="brush: bash">> express --help Usage: express [options] [dir] @@ -63,7 +63,7 @@ translation_of: Learn/Server-side/Express_Nodejs/skeleton_website <p>Команда <code>express</code> создаст проект в <em>текущем</em> каталоге с использованием (устаревшего) движка представления <em>Jade</em> и обычного CSS. Если указать <font face="Courier New, monospace">express </font><font face="Courier New, monospace">name</font>, проект будет создан в подкаталоге name текущего каталога. </p> -<pre class="brush: bash notranslate"><code>express</code></pre> +<pre class="brush: bash"><code>express</code></pre> <p>Можно выбрать движок представления (шаблон), используя --<code>view; </code><code><font face="Times New Roman, serif">параметр</font></code><code> --</code><code>css </code> позволяет выбрать движок для создания CSS.</p> @@ -127,12 +127,12 @@ translation_of: Learn/Server-side/Express_Nodejs/skeleton_website <p>Выберем место для нового проекта — каталог <font face="Courier New, monospace">express-locallibrary-tutorial - </font><font face="Times New Roman, serif">и выполним</font><font face="Courier New, monospace"> </font>команду:</p> -<pre class="brush: bash notranslate">express express-locallibrary-tutorial --view=pug +<pre class="brush: bash">express express-locallibrary-tutorial --view=pug </pre> <p>Будет создан каталог <font face="Courier New, monospace">express-locallibrary-tutorial </font><font face="Times New Roman, serif">и выведен список созданных внутри каталога проектных файлов</font>.</p> -<pre class="brush: bash notranslate"> create : express-locallibrary-tutorial +<pre class="brush: bash"> create : express-locallibrary-tutorial create : express-locallibrary-tutorial/package.json create : express-locallibrary-tutorial/app.js create : express-locallibrary-tutorial/public/images @@ -169,16 +169,16 @@ translation_of: Learn/Server-side/Express_Nodejs/skeleton_website <ol> <li>Прежде всего установим зависимости (команда <code>install</code> запросит все пакеты зависимостей, указанные в файле<strong> package.json</strong>). - <pre class="brush: bash notranslate">cd express-locallibrary-tutorial + <pre class="brush: bash">cd express-locallibrary-tutorial npm install</pre> </li> <li>Затем запустим приложение. <ul> <li>В Windows используйте команду: - <pre class="brush: bash notranslate">SET DEBUG=express-locallibrary-tutorial:* & npm start</pre> + <pre class="brush: bash">SET DEBUG=express-locallibrary-tutorial:* & npm start</pre> </li> <li>В Mac OS X или Linux используйте команду: - <pre class="brush: bash notranslate">DEBUG=express-locallibrary-tutorial:* npm start + <pre class="brush: bash">DEBUG=express-locallibrary-tutorial:* npm start </pre> </li> </ul> @@ -193,7 +193,7 @@ npm install</pre> <div class="note"> <p><strong>Примечание:</strong> Можно также запустить приложение командой <code>npm start</code>. Переменная DEBUG, указанная в примере, включает логирование в консоль для дальнейшей отладки. Так, при посещении страницы веб-приложения, вы увидите похожий вывод в консоль:</p> -<pre class="brush: bash notranslate">>SET DEBUG=express-locallibrary-tutorial:* & npm start +<pre class="brush: bash">>SET DEBUG=express-locallibrary-tutorial:* & npm start > express-locallibrary-tutorial@0.0.0 start D:\express-locallibrary-tutorial > node ./bin/www @@ -212,7 +212,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>Одно из самых простых средств для этого --<br> <a href="https://github.com/remy/nodemon">nodemon</a>. Его обычно устанавливают глобально (так как это "инструмент"), но сейчас мы установим его и будем применять локально как зависимость разработки, так что любые разработчики проекта получат его автоматически при установке приложения. Выполним следующую команду (предполагаем, что мы находимся в корневом каталоге):</p> -<pre class="brush: bash notranslate">npm install --save-dev nodemon</pre> +<pre class="brush: bash">npm install --save-dev nodemon</pre> @@ -220,20 +220,20 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> -<pre class="notranslate"><code><font color="#333333"><font face="Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace"><font size="3">npm install -g nodemon</font></font></font></code></pre> +<pre><code><font color="#333333"><font face="Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace"><font size="3">npm install -g nodemon</font></font></font></code></pre> <p>В файле <strong>package.json </strong>проекта появится новый раздел с этой зависимостью (на вашей машине номер версии nodemon может быть другим) :</p> -<pre class="brush: json notranslate"> "devDependencies": { +<pre class="brush: json"> "devDependencies": { "nodemon": "^1.11.0" } </pre> <p>Поскольку nodemon не установлен глобально, его нельзя запустить из командной строки (пока мы не добавим его в путь), но его можно вызвать из сценария NPM, так как NPM знает все об установленных пакетах. Раздел <code>scripts</code> в файле package.json исходно будет содержать одну строку, которая начинается с <code>"start"</code>. Обновите его, поставив запятую в конце строки, и добавьте строку <code>"devstart",</code> показанную ниже:</p> -<pre class="brush: json notranslate"> "scripts": { +<pre class="brush: json"> "scripts": { "start": "node ./bin/www"<strong>,</strong> <strong> "devstart": "nodemon ./bin/www"</strong> }, @@ -245,13 +245,13 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <li>В Windows:</li> </ul> -<pre class="brush: bash notranslate">SET DEBUG=express-locallibrary-tutorial:* & npm <strong>run devstart</strong></pre> +<pre class="brush: bash">SET DEBUG=express-locallibrary-tutorial:* & npm <strong>run devstart</strong></pre> <ul> <li>Для macOS или Linux:</li> </ul> -<pre class="notranslate"><code>DEBUG=express-locallibrary-tutorial:* npm <strong>run devstart</strong></code></pre> +<pre><code>DEBUG=express-locallibrary-tutorial:* npm <strong>run devstart</strong></code></pre> <div class="note"> <p><strong>Примечание:</strong> Сейчас после изменения любого файла проекта сервер будет перезапускаться (или можно самостоятельно перезапустить его, введя <code>rs</code> в командной строке). Вам всё равно придётся обновить страницу в браузере .</p> @@ -267,7 +267,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>После установки зависимостей проект имеет такую структуру файлов (файлы - это элементы <strong>без </strong>префикса"/"). Файл <strong>package.json</strong> определяет имя файла с приложением, сценарии запуска, зависимости и др. Сценарий запуска задаёт точку входа приложения, у нас -- файл JavaScript <strong>/bin/www</strong>. Этот файл настраивает некоторые обработчики ошибок приложения, а затем загружает <strong>app.js </strong>для выполнения остальной работы. Пути приложения хранятся в отдельных модулях каталога <strong>routes/</strong>. Шаблоны хранятся в каталоге /<strong>views</strong>.</p> -<pre class="notranslate">/express-locallibrary-tutorial +<pre>/express-locallibrary-tutorial <strong>app.js</strong> /bin <strong>www</strong> @@ -295,7 +295,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>Файл <strong>package.json </strong>указывает зависимости приложения и содержит другие данные:</p> -<pre class="brush: json notranslate">{ +<pre class="brush: json">{ "name": "express-locallibrary-tutorial", "version": "0.0.0", "private": true, @@ -329,7 +329,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>Раздел "scripts" определяет скрипт" start", выполняемый при запуске сервера командой <code>npm start</code>. Можно видеть, что самом деле выполняется команда node <strong>./bin/www</strong>. Кроме того, определяется script "<em>devstart</em>", который вызывается командой <code>npm run devstart</code>. Запускается тот же файл <strong>./bin/www</strong> ,но командой <em>nodemon</em> вместо <em>node</em>.</p> -<pre class="notranslate"><code>"scripts": { +<pre><code>"scripts": { "start": "node ./bin/www", "devstart": "nodemon ./bin/www" },</code></pre> @@ -338,7 +338,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>Файл <strong>/bin/www</strong> – это входная точка приложения. Сначала в файле создаётся объект основного приложения, расположенного в app.js — выполняется app=<code>require(./</code><code>app</code><code>).</code></p> -<pre class="brush: js notranslate">#!/usr/bin/env node +<pre class="brush: js">#!/usr/bin/env node /** * Module dependencies. @@ -357,7 +357,7 @@ GET /favicon.ico 404 34.134 ms - 1335</pre> <p>Этот файл создаёт объект приложения <code>express </code>(с именем<code>app</code>, по соглашению), настраивает приложение и промежуточное ПО, а затем экспортирует приложение из модуля. В приведённом ниже коде показаны только те части файла, которые создают и экспортируют объект приложения:</p> -<pre class="brush: js notranslate"><code>var express = require('express'); +<pre class="brush: js"><code>var express = require('express'); var app = express(); ... </code>module.exports = app; @@ -367,7 +367,7 @@ var app = express(); <p>Рассмотрим детали файла app.js. Сначала при помощи require(...) выполняется импорт некоторых полезных библиотек node: <em>express,</em> s<em>erve-favicon</em>, <em>morgan</em>, <em>cookie-parse, body-parser </em>(они ранее были загружены для нашего приложения командой npm install), а также path из основной библиотеки node (применяется для разбора путей каталогов и файлов).</p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); @@ -377,7 +377,7 @@ var bodyParser = require('body-parser'); <p>Затем require запрашивает модули из каталога путей route. Эти модули и файлы содержат код для обработки конкретного набора соответствующих путей (URL маршрутов). Если мы расширим каркас приложения, например, чтобы получить список книг библиотеки, нам следует добавить новый файл для обработки пути, связанного с книгами.</p> -<pre class="brush: js notranslate">var index = require('./routes/index'); +<pre class="brush: js">var index = require('./routes/index'); var users = require('./routes/users'); </pre> @@ -387,7 +387,7 @@ var users = require('./routes/users'); <p>Далее, импортированные модули express применяются для создания объекта app, который потом устанавливает движки-шаблоны представления. Установка движков состоит их двух частей. В первой мы задаём значение 'view', указывая папку, в которой будут размещаться шаблоны (у нас это /views). Во второй мы задаём значение движка 'view engine', указывая на библиотеку шаблона (у нас — "pug").</p> -<pre class="brush: js notranslate">var app = express(); +<pre class="brush: js">var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); @@ -396,7 +396,7 @@ app.set('view engine', 'pug'); <p>Следующие строки вызывают app.use(...), чтобы добавить промежуточные (middleware) библиотеки в цепочку обработки запросов. Кроме сторонних библиотек, импортированных ранее, используем библиотеку Express.static, что позволит обрабатывать статические файлы из папки <strong>/public </strong>корня проекта.</p> -<pre class="brush: js notranslate">// uncomment after placing your favicon in /public +<pre class="brush: js">// uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); @@ -407,7 +407,7 @@ app.use(cookieParser()); <p>Теперь, когда промежуточные библиотеки настроены, мы добавляем (импортированный ранее) код обработки путей в цепочку обработки запросов. Импортированный код будет задавать отдельные пути для разных частей сайта:</p> -<pre class="brush: js notranslate">app.use('/', index); +<pre class="brush: js">app.use('/', index); app.use('/users', users); </pre> @@ -417,7 +417,7 @@ app.use('/users', users); <p>Последняя в файле промежуточная библиотека добавляет методы обработки ошибок и ответов 404 от HTTP.</p> -<pre class="brush: js notranslate">// catch 404 and forward to error handler +<pre class="brush: js">// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; @@ -438,13 +438,13 @@ app.use(function(err, req, res, next) { <p>Объект app приложения Express теперь полностью настроен. Остался последний шаг - добавить его к экспортируемым элементам модуля (это позволит импортировать его в файле <strong>/bin/www</strong>).</p> -<pre class="brush: js notranslate">module.exports = app;</pre> +<pre class="brush: js">module.exports = app;</pre> <h3 id="Пути_Routes">Пути (Routes)</h3> <p>Файл путей /routes/users.js приведён ниже (файлы путей имеют сходную структуру, поэтому нет необходимости приводить также index.js). Сначала загружается модуль Express, затем он используется для получения объекта express.Router. После этого для этого объекта задаётся путь, и, наконец, объект-роутер экспортируется из модуля (именно это позволяет импортировать файл в app.js):.</p> -<pre class="brush: js notranslate">var express = require('express'); +<pre class="brush: js">var express = require('express'); var router = express.Router(); /* GET users listing. */ @@ -467,7 +467,7 @@ module.exports = router; <p>Файлы преставлений (шаблонов) хранятся в каталоге <strong><font color="#333333"><font face="Arial, x-locale-body, sans-serif"><font size="3">/views </font></font></font></strong><font color="#333333"><font face="Times New Roman, serif"><font size="3">(это указано в </font></font><font face="Courier New, monospace"><font size="3">app.js</font></font><font face="Times New Roman, serif"><font size="3">) и имеют расширение</font></font></font><strong><font color="#333333"><font face="Times New Roman, serif"><font size="3"> </font></font></font></strong><strong>.pug</strong>. Метод <code><a href="http://expressjs.com/en/4x/api.html#res.render">Response.render()</a></code> выполняет указанный шаблон, передавая объекту значение именованной переменной, и затем посылает результат как ответ. В коде из <strong>/routes/index.js</strong> (приводится ниже) можно увидеть, что роут отвечает, используя шаблон "index" с переданным значением переменной "title" из шаблона.</p> -<pre class="brush: js notranslate">/* GET home page. */ +<pre class="brush: js">/* GET home page. */ router.get('/', function(req, res) { res.render('index', { title: 'Express' }); }); @@ -475,7 +475,7 @@ router.get('/', function(req, res) { <p>Шаблон для пути '/' приведён ниже (файл <strong>index.pug</strong>). О синтаксисе мы поговорим позже. Сейчас важно знать, что переменная title со значением 'Express' помещена в определённое место шаблона.</p> -<pre class="notranslate">extends layout +<pre>extends layout block content h1= title diff --git a/files/ru/learn/server-side/first_steps/client-server_overview/index.html b/files/ru/learn/server-side/first_steps/client-server_overview/index.html index 38168b8a5d..5521c93ef0 100644 --- a/files/ru/learn/server-side/first_steps/client-server_overview/index.html +++ b/files/ru/learn/server-side/first_steps/client-server_overview/index.html @@ -82,7 +82,7 @@ translation_of: Learn/Server-side/First_steps/Client-Server_overview <p>Каждая строка запроса содержит информацию о запросе. Первая часть называется <strong>заголовок</strong> и содержит важную информацию о запросе, точно так же, как <a href="https://developer.mozilla.org/ru/docs/Learn/HTML/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2_HTML/The_head_metadata_in_HTML">HTML head</a> содержит важную информацию о HTML-документе (но не содержимое документа, которое расположено внутри тэга "body"):</p> -<pre class="notranslate">GET https://developer.mozilla.org/en-US/search?q=client+server+overview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev HTTP/1.1 +<pre>GET https://developer.mozilla.org/en-US/search?q=client+server+overview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev HTTP/1.1 Host: developer.mozilla.org Connection: keep-alive Pragma: no-cache @@ -132,7 +132,7 @@ Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; csrftoken=zIPUJsAZv6pcgCBJSC <p>В конце сообщения мы видим содержимое <strong>body, </strong>содержащее HTML-код возвращаемого ответа.</p> -<pre class="brush: html notranslate">HTTP/1.1 200 OK +<pre class="brush: html">HTTP/1.1 200 OK Server: Apache X-Backend-Server: developer1.webapp.scl3.mozilla.com Vary: Accept,Cookie, Accept-Encoding @@ -166,7 +166,7 @@ Content-Length: 41823 <p>В приведённом ниже тексте показан HTTP-запрос, сделанный когда пользователь загружает новые данные профиля на этом сайте. Формат запроса почти такой же, как пример запроса <code>GET</code>, показанный ранее, хотя первая строка идентифицирует этот запрос как <code>POST</code>.</p> -<pre class="brush: html notranslate">POST https://developer.mozilla.org/en-US/profiles/hamishwillee/edit HTTP/1.1 +<pre class="brush: html">POST https://developer.mozilla.org/en-US/profiles/hamishwillee/edit HTTP/1.1 Host: developer.mozilla.org Connection: keep-alive Content-Length: 432 @@ -190,7 +190,7 @@ csrfmiddlewaretoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT&user-username=hamishwil <p>Ответ от запроса показан ниже. Код состояния «<code>302 Found</code>» сообщает браузеру, что сообщение обработано, и что необходим второй HTTP-запрос для загрузки страницы, указанной в поле <code>Location</code>. В остальном информация аналогична информации для ответа на запрос <code>GET</code> .</p> -<pre class="brush: html notranslate">HTTP/1.1 302 FOUND +<pre class="brush: html">HTTP/1.1 302 FOUND Server: Apache X-Backend-Server: developer3.webapp.scl3.mozilla.com Vary: Cookie @@ -277,7 +277,7 @@ Content-Length: 0 <p>Для примера рассмотрим следующий код Django (Python), который связывает два URL-шаблона с двумя функциями просмотра. Первый шаблон проверяет, что HTTP-запрос с URL-адресом ресурса <code>/best</code> будет передан функции с именем <code>index()</code> в модуле <code>views</code>. Запрос, который имеет шаблон «<code>/best/junior</code>», вместо этого будет передан функции просмотра <code>junior()</code>.</p> -<pre class="brush: python notranslate"># file: best/urls.py +<pre class="brush: python"># file: best/urls.py # from django.conf.urls import url @@ -299,7 +299,7 @@ urlpatterns = [ <p>В приведённом ниже примере представлен список всех команд, у которых есть точный (с учётом регистра) <code>team_type</code> «junior» («младший») — обратите внимание на формат: имя поля (<code>team_type</code>), за которым следует двойной знак подчёркивания, а затем тип соответствия для использования (в этом случае <code>exact</code> («точное»)). Существует много других типов соответствия, и мы можем объединить их. Мы также можем контролировать порядок и количество возвращаемых результатов.</p> -<pre class="brush: python notranslate">#best/views.py +<pre class="brush: python">#best/views.py from django.shortcuts import render diff --git a/files/ru/learn/server-side/first_steps/web_frameworks/index.html b/files/ru/learn/server-side/first_steps/web_frameworks/index.html index 54d00a7baf..ec0f7368c9 100644 --- a/files/ru/learn/server-side/first_steps/web_frameworks/index.html +++ b/files/ru/learn/server-side/first_steps/web_frameworks/index.html @@ -47,7 +47,7 @@ translation_of: Learn/Server-side/First_steps/Web_frameworks <p>Пример ниже показывает, как это работает в веб-фреймворке Django (Python). Каждая функция «view» (обработчик запроса) получает объект <code>HttpRequest</code>, содержащий информацию о запросе, и должна вернуть объект <code>HttpResponse</code> с форматированным выводом (в этом случае строка).</p> -<pre class="brush: python notranslate"># Django view function +<pre class="brush: python"># Django view function from django.http import HttpResponse def index(request): @@ -63,13 +63,13 @@ def index(request): <p>Различные фреймворки используют различные механизмы для сопоставления. Например, веб-фреймворк Flask (Python) добавляет маршруты для просмотра функций используя декораторы.</p> -<pre class="brush: python notranslate">@app.route("/") +<pre class="brush: python">@app.route("/") def hello(): return "Hello World!"</pre> <p>Django ожидает, что разработчики определят список сопоставлений URL-адресов между шаблоном URL-адреса и функцией просмотра.</p> -<pre class="brush: python notranslate">urlpatterns = [ +<pre class="brush: python">urlpatterns = [ url(r'^$', views.index), # example: /best/myteamname/5/ url(r'^best/(?P<team_name>\w.+?)/(?P<team_number>[0-9]+)/$', views.best), @@ -97,7 +97,7 @@ def hello(): <br> Первый фрагмент кода ниже показывает очень простую модель Django для объекта</span> <code>Team</code><span class="tlid-translation translation" lang="ru">. Это сохраняет название команды и уровень команды как символьные поля и определяет максимальное количество символов для каждой записи.</span> <code>team_level</code><span class="tlid-translation translation" lang="ru"> </span>—<span class="tlid-translation translation" lang="ru"> это поле выбора, поэтому здесь мы связываем варианты значений на выбор с сохраняемыми данными, а также значение по умолчанию.</span></p> -<pre class="brush: python notranslate">#best/models.py +<pre class="brush: python">#best/models.py from django.db import models @@ -117,7 +117,7 @@ class Team(models.Model): <br> <span title="">Второй фрагмент кода показывает функцию представления (обработчик ресурсов) для отображения всех наших команд U09.</span> <span title="">В этом случае мы указываем, что мы хотим фильтровать для всех записей, где поле</span></span> <code>team_level</code> <span class="tlid-translation translation" lang="ru"><span title="">имеет в точности текст «U09» (обратите внимание ниже, как этот критерий передаётся функции</span></span> <code>filter()</code> <span class="tlid-translation translation" lang="ru"><span title="">в качестве аргумента с именем поля и типом соответствия, отделённым двойным</span> <span title="">подчёркиванием: <strong>team_level__exact</strong>).</span></span></p> -<pre class="brush: python notranslate">#best/views.py +<pre class="brush: python">#best/views.py from django.shortcuts import render from .models import Team @@ -145,7 +145,7 @@ def youngest(request): <p><span class="tlid-translation translation" lang="ru"><span title="">Фрагмент кода ниже показывает, как это работает.</span> <span title="">Продолжая пример «самой молодой команды» из предыдущего раздела, HTML-шаблон передаёт представлению переменную списка</span></span> <code>youngest_teams</code><span class="tlid-translation translation" lang="ru"><span title="">.</span> <span title="">Внутри скелета HTML у нас есть выражение, которое сначала проверяет, существует ли переменная <code>youngest_teams</code>, а затем повторяет её в цикле <code>for</code>.</span> <span title="">На каждой итерации шаблон отображает значение <code>team_name</code> команды в элементе списка.</span></span></p> -<pre class="brush: html notranslate">#best/templates/best/index.html +<pre class="brush: html">#best/templates/best/index.html <!DOCTYPE html> <html lang="en"> diff --git a/files/ru/learn/server-side/first_steps/website_security/index.html b/files/ru/learn/server-side/first_steps/website_security/index.html index 1f976dd741..912fa2c0d5 100644 --- a/files/ru/learn/server-side/first_steps/website_security/index.html +++ b/files/ru/learn/server-side/first_steps/website_security/index.html @@ -73,11 +73,11 @@ original_slug: Learn/Server-side/First_steps/Веб_Безопасность <br> <span title="">Эта уязвимость присутствует, если пользовательский ввод, который передаётся в базовый оператор SQL, может изменить смысл оператора.</span> <span title="">Например, следующий код предназначен для перечисления всех пользователей с определённым именем (userName), которое было предоставлено из формы HTML:</span></span></p> -<pre class="brush: sql notranslate">statement = "SELECT * FROM users WHERE name = '" + <strong>userName</strong> + "';"</pre> +<pre class="brush: sql">statement = "SELECT * FROM users WHERE name = '" + <strong>userName</strong> + "';"</pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Если пользователь указывает реальное имя, оператор будет работать так, как задумано.</span> <span title="">Однако злонамеренный пользователь может полностью изменить поведение этого оператора SQL на новый оператор в следующем примере, просто указав текст полужирным шрифтом для userName.</span></span></p> -<pre class="brush: sql notranslate">SELECT * FROM users WHERE name = '<strong>a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't</strong>'; +<pre class="brush: sql">SELECT * FROM users WHERE name = '<strong>a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't</strong>'; </pre> <p><span class="tlid-translation translation" lang="ru"><span title="">Модифицированный оператор создаёт действительный оператор SQL, который удаляет таблицу пользователей и выбирает все данные из таблицы userinfo (которая раскрывает информацию о каждом пользователе).</span> <span title="">Это работает, потому что первая часть введённого текста (a ';) завершает исходное утверждение.</span><br> @@ -90,7 +90,7 @@ original_slug: Learn/Server-side/First_steps/Веб_Безопасность <p>В следующей инструкции мы экранируем символ '. Теперь SQL будет интерпретировать имя как всю строку, выделенную жирным шрифтом (это действительно очень странное имя, но безопасное).</p> -<pre class="brush: sql notranslate">SELECT * FROM users WHERE name = '<strong>a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t'</strong>; +<pre class="brush: sql">SELECT * FROM users WHERE name = '<strong>a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t'</strong>; </pre> |