Главная страница

Книга Изучаем Python


Скачать 4.68 Mb.
НазваниеКнига Изучаем Python
Дата10.12.2022
Размер4.68 Mb.
Формат файлаpdf
Имя файлаErik_Metiz_Izuchaem_Python_Programmirovanie_igr_vizualizatsia_da.pdf
ТипКнига
#837531
страница44 из 53
1   ...   40   41   42   43   44   45   46   47   ...   53
395
Так как мы сейчас всего лишь убеждаемся в том, что Learning Log работает, как по- ложено, страница пока останется простой. Когда приложение будет завершено, вы можете заниматься его оформлением, сколько душе угодно; приложение, которое хорошо выглядит, но не работает, бессмысленно. Пока на домашней странице будет отображаться только заголовок и краткое описание.
Сопоставление URL
Пользователь запрашивает страницы, вводя URL-адреса в браузере и щелкая на ссылках, поэтому мы должны решить, какие URL-адреса понадобятся в нашем проекте. Начнем с URL домашней страницы: это базовый адрес, используемый для обращения к проекту. На данный момент базовый URL-адрес http://localhost:8000/ возвращает сайт, сгенерированный Django по умолчанию; он сообщает о том, что проект был создан успешно. Мы изменим домашнюю страницу, связав базовый
URL-адрес с домашней страницей Learning Log.
В каталоге проекта learning_log откройте файл urls .py
. Вы увидите в нем следу- ющий код:
urls.py
 from django.conf.urls import include, url from django.contrib import admin
 urlpatterns = [
 url(r'^admin/', include(admin.site.urls)),
]
Первые две строки импортируют функции и модули, управляющие URL-адресами проекта и административным сайтом . В теле файла определяется переменная urlpatterns
. В файле urls .py
, представляющем проект в целом, переменная urlpatterns включает наборы URL-адресов из приложений в проект. Код  включает модуль admin.site.urls
, определяющий все URL-адреса, которые могут запрашиваться с административного сайта.
Добавим в этот файл URL-адреса learning_logs
:
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
 url(r'', include('learning_logs.urls', namespace='learning_ logs')),
]
В точке  добавляется строка включения модуля learning_logs.urls
. Эта строка включает аргумент namespace
, по которому URL-адреса learning_logs можно от- личить от других URL-адресов, которые могут появиться в проекте. Данная воз- можность может оказаться чрезвычайно полезной по мере роста проекта.
Файл urls .py по умолчанию находится в каталоге learning_log
; теперь нужно создать второй файл urls .py в папке learning_logs
:

396 Глава 18 • Знакомство с Django
urls.py

"""Определяет схемы URL для learning_logs."""
 from django.conf.urls import url
 from . import views
 urlpatterns = [
# Домашняя страница
 url(r'^$', views.index, name='index'),
]
Чтобы было понятно, с какой версией urls .py мы работаем, в начало файла добавля- ется строка документации . Затем импортируется функция url
, она необходима для связывания URL с представлениями . Также импортируется модуль views
; точка приказывает Python импортировать представления из каталога, в котором находится текущий модуль urls .py
. Переменная urlpatterns в этом модуле пред- ставляет собой список страниц, которые могут запрашиваться из приложения learning_logs
.
Схема URL представляет собой вызов функции url()
с тремя аргументами .
Первый аргумент содержит регулярное выражение. Django ищет в urlpatterns регулярное выражение, совпадающее со строкой запрашиваемого URL. Таким образом, регулярное выражение должно определять схему адреса, которую будет искать Django.
Возьмем регулярное выражение r'^$'
. Символ r
сообщает Python, что после- дующая строка должна интерпретироваться без дополнительной обработки, а апострофы указывают, где начинается и заканчивается регулярное выражение.
Символ
^
обозначает начало строки, а символ
$
обозначает ее конец. В целом это выражение приказывает Python искать URL-адрес, не содержащий ничего между началом и концом URL. Python игнорирует базовый URL-адрес проекта
(http://localhost:8000/), так что пустое регулярное выражение совпадает с базовым
URL-адресом. Любой другой URL-адрес не будет соответствовать этому выраже- нию, и Django вернет страницу с ошибкой, если запрашиваемый URL не соответ- ствует ни одной из существующих схем URL.
Второй аргумент url()
 определяет вызываемую функцию представления. Ког- да запрашиваемый URL-адрес соответствует регулярному выражению, Django вызывает views.index
(мы напишем эту функцию представления в следующем разделе). Третий аргумент определяет index для этой схемы URL, чтобы на нее можно было ссылаться в других частях кода. Каждый раз, когда потребуется предоставить ссылку на домашнюю страницу, мы будем использовать это имя вместо URL.
ПРИМЕЧАНИЕ
Регулярные выражения используются почти во всех языках программирования . Они чрезвычайно полезны, но, чтобы освоить их, понадобится время . Если что-то осталось непонятным, не беспо- койтесь; в ходе работы над проектом мы рассмотрим много примеров .

Начало работы над приложением 397
Написание представления
Функция представления получает информацию из запроса, подготавливает данные, необходимые для построения страницы, и возвращает данные браузеру — часто с использованием шаблона, определяющего внешний вид страницы.
Файл views .py в learning_logs был сгенерирован автоматически при выполнении ко- манды python manage.py startapp
. На данный момент его содержимое выглядит так:
views.py
from django.shortcuts import render
# Создайте здесь свои представления.
Сейчас файл только импортирует функцию render()
, которая генерирует ответ на основании данных, полученных от представлений. Представление домашней страницы должно быть записано в следующем виде:
from django.shortcuts import render def index(request):
"""Домашняя страница приложения Learning Log"""
return render(request, 'learning_logs/index.html')
Если URL запроса совпадает с только что определенной схемой, Django ищет в файле views .py функцию с именем index()
, после чего передает этой функции представления объект запроса. В нашем случае никакая обработка данных для страницы не нужна, поэтому код функции сводится к вызову render()
. Функция render()
использует два аргумента — исходный объект запроса и шаблон, исполь- зуемый для построения страницы. Давайте напишем этот шаблон.
Написание шаблона
Шаблон задает структуру веб-страницы. Он определяет общий внешний вид, а Django заполняет его соответствующими данными при каждом запросе страницы.
Шаблон может обращаться к любым данным, полученным от представления. Так как наше представление домашней страницы никаких данных не предоставляет, шаблон получается относительно простым.
В каталоге learning_logs создайте новый каталог с именем templates
. В каталоге templates создайте другой каталог с именем learning_logs
. На первый взгляд такая структура кажется избыточной (каталог learning_logs в каталоге templates внутри каталога learning_logs
), но созданная таким образом структура будет однозначно интерпретироваться Django даже в контексте большого проекта, состоящего из мно- жества отдельных приложений. Во внутреннем каталоге learning_logs создайте новый файл с именем index .html
. Включите в него следующий текст:
index.html
Learning Log
Learning Log helps you keep track of your learning, for any topic you're learning about.

398 Глава 18 • Знакомство с Django
Это очень простой файл. Если вы не знакомы с синтаксисом HTML, теги обозначают абзацы. Тег открывает абзац, а тег закрывает его. Наша стра- ница содержит два абзаца: первый содержит заголовок, а второй описывает, что пользователь может сделать с помощью приложения Learning Log.
Теперь при запросе базового URL-адреса проекта http://localhost:8000/ вы увидите только что построенную страницу вместо страницы по умолчанию. Django берет запрошенный URL-адрес и видит, что он совпадает со схемой r'^$'
; в этом случае
Django вызывает функцию views.index()
, что приводит к построению страницы с использованием шаблона, содержащегося в index .html
. Полученная страница по- казана на рис. 18.3.
Рис. 18.3. Домашняя страница Learning Log
И хотя может показаться, что для одной страницы этот процесс слишком сло- жен, такое разделение URL-адресов, представлений и шаблонов работает хоро- шо. Оно позволяет сосредоточиться на отдельных аспектах проекта, а в более крупных проектах отдельные участники могут сосредоточиться на тех областях, в которых они наиболее сильны. Например, специалист по базам данных может заняться моделями, программист — кодом представления, а веб-дизайнер — ша- блонами.
УПРАЖНЕНИЯ
18-5 . План питания: представьте приложение для составления плана питания на неделю .
Создайте новый каталог с именем meal_planner, затем создайте в этом каталоге новый про- ект Django . Создайте новое приложение с именем meal_plans . Постройте простую домаш- нюю страницу для этого проекта .
18-6 . Домашняя страница Pizzeria: добавьте домашнюю страницу в проект Pizzeria, который вы начали строить в упражнении 18-4 (с . 394) .
Построение других страниц
Теперь, когда вы начали представлять процесс построения страниц, можно пере- ходить к построению проекта Learning Log. Мы создадим две страницы для вывода данных: на одной будет выводиться список всех тем, а на другой — все записи по кон- кретной теме. Для каждой страницы мы создадим схему URL, напишем функцию

Построение других страниц 399
представления и создадим шаблон. Но, прежде чем переходить к работе, стоит создать базовый шаблон, от которого будут наследовать все шаблоны этого проекта.
Наследование шаблонов
При построении сайта некоторые элементы почти всегда повторяются на каждой странице. Вместо того чтобы встраивать эти элементы непосредственно в страницы, вы можете написать базовый шаблон с повторяющимися элементами; все страницы будут наследовать от этого шаблона. Такое решение позволит сосредоточиться на разработке уникальных аспектов каждой страницы и существенно упростит изменение общего оформления проекта в целом.
Родительский шаблон
Начнем с создания шаблона base .html в одном каталоге с файлом index .html
. Этот файл будет содержать элементы, общие для всех страниц; все остальные шаблоны наследуют от base .html
. Пока единственным элементом, который должен повто- ряться на каждой странице, остается заголовок в верхней части страницы. Так как шаблон будет включаться в каждую страницу, преобразуем заголовок в ссылку на домашнюю страницу:
base.html

Learning Log

{% block content %}{% endblock content %}
Первая часть файла создает абзац с именем проекта, который также работает как ссылка на домашнюю страницу. Для построения ссылки использовался шаблонный
тег, обозначенный фигурными скобками и знаками
%
{%
%}
. Шаблонный тег пред- ставляет собой блок кода, который генерирует информацию для вывода на страни- це. В данном примере шаблонный тег
{%
url
'learning_logs:index'
%}
генерирует
URL-адрес, соответствующий схеме URL, определенной в файле learning_logs/urls .
py с именем 'index'
. В данном примере learning_logs
— пространство имен, а index
— схема URL с уникальным именем в этом пространстве имен.
В этой простой странице HTML ссылка заключается в якорный тег:
url_ссылки
">текст ссылки
Генерирование URL-адреса шаблонным тегом существенно упрощает актуа- лизацию ссылок. Чтобы изменить URL-адрес в проекте, достаточно изменить схему URL в urls .py
, а Django автоматически вставит обновленный URL-адрес при следующем запросе страницы. Каждая страница в проекте будет наследовать от base .html
, так что в дальнейшем на каждой странице будет содержаться ссылка на домашнюю страницу.
В точке  вставляется пара тегов block
. Блок с именем content резервирует место; информация, попадающая в блок content
, будет определяться дочерним шаблоном.

400 Глава 18 • Знакомство с Django
Дочерний шаблон не обязан определять каждый блок в своем родителе, так что в родительских шаблонах можно зарезервировать место для любого количе- ства блоков, а дочерний шаблон будет использовать столько из них, сколько по- требуется.
ПРИМЕЧАНИЕ
В коде Python почти всегда используются отступы в четыре пробела . Файлы шаблонов обычно имеют больший уровень вложенности, чем файлы Python, поэтому каждый уровень отступа обычно обозначается двумя пробелами .
Дочерний шаблон
Теперь нужно переписать файл index .html так, чтобы он наследовал от base .html
Обновленный файл index .html выглядит так:
index.htm

{% extends "learning_logs/base.html" %}

{% block content %}
Learning Log helps you keep track of your learning, for any topic you're learning about.

{% endblock content %}
Сравнивая этот файл с исходной версией index .html
, мы видим, что заголовок
Learning Log заменен кодом наследования от родительского шаблона . В первой строке дочернего шаблона должен находиться тег
{%
extends
%}
, который сообщает
Django, от какого родительского шаблона он наследует. Файл base .html является частью learning_logs
, поэтому learning_logs включается в путь к родительскому шаблону. Эта строка извлекает все содержимое из шаблона base .html и позволяет index .html определить, что должно попасть в пространство, зарезервированное блоком content
Блок content определяется в точке  вставкой тега
{%
block
%}
с именем content
Все, что не наследуется от родительского шаблона, попадает в блок content
В данном случае это абзац с описанием проекта Learning Log. В точке  мы сообщаем о том, что определение content завершено, при помощи тега
{%
endblock content
%}
Вероятно, вы уже начинаете понимать преимущества наследования шаблонов: в до- черний шаблон достаточно включить информацию, уникальную для этой страницы.
Такой подход упрощает не только каждый шаблон, но и изменение сайта. Чтобы изменить элемент, общий для многих страниц, достаточно изменить элемент в ро- дительском шаблоне. Внесенные изменения будут автоматически перенесены на каждую страницу, наследующую от этого шаблона. В проекте из десятков и сотен страниц такая структура значительно упрощает и ускоряет доработку сайта.
ПРИМЕЧАНИЕ
В больших проектах часто создается один родительский шаблон base .html для всего сайта и ро- дительские шаблоны для каждого крупного раздела сайта . Все шаблоны разделов наследуют от base .html, и каждая страница сайта наследует от шаблона раздела . При такой структуре вы смо-

Построение других страниц 401
жете легко изменять оформление и поведение сайта в целом, любого его раздела или отдельной страницы . Данная конфигурация сильно повышает эффективность работы и стимулирует разработ- чика к дальнейшему совершенствованию сайта .
Страница со списком тем
Разобравшись с тем, как эффективно организовать построение страниц, мы можем сосредоточиться на следующих двух страницах: списке всех тем и списке записей по одной теме. На странице тем выводится перечень всех тем, созданных пользо- вателями, и это первая страница, на которой нам придется работать с данными.
Схема URL для тем
Сначала нужно определить URL для страницы тем. Обычно в таких случаях выбирается простой фрагмент URL, который отражает суть информации, пред- ставленной на странице. Мы воспользуемся словом topics, так что для получения страницы будет использоваться URL http://localhost:8000/topics/. А вот какие из- менения следует внести в learning_logs/urls .py
:
urls.py
"""Определяет схемы URL для learning_logs."""
urlpatterns = [
# Домашняя страница url(r'^$', views.index, name='index'),
# Вывод всех тем.
 url(r'^topics/$', views.topics, name='topics'),
]
Мы просто добавили topics/
в аргумент регулярного выражения, используемый с URL-адресом домашней страницы . Когда Django проверяет запрашиваемый
URL-адрес, эта схема совпадет с любым URL-адресом, который состоит из базо- вого URL-адреса и слова topics
. Косую черту в конце можно включить, можно не включать, но после слова topics ничего быть не должно, иначе схема не совпа- дет. Любой запрос с URL-адресом, соответствующим этой схеме, будет передан функции topics()
в views .py
Представление topics
Функция topics()
должна получать данные из базы данных и отправлять их ша- блону. Обновленная версия views .py выглядит так:
views.py
from django.shortcuts import render

from .models import Topic def index(request):

402 Глава 18 • Знакомство с Django
 def topics(request):
"""Выводит список тем."""
 topics = Topic.objects.order_by('date_added')
 context = {'topics': topics}
 return render(request, 'learning_logs/topics.html', context)
Сначала импортируется модель, связанная с нужными данными . Функции topics()
необходим один параметр: объект запроса, полученный Django от сер- вера . В точке  выдается запрос к базе данных на получение объектов
Topic
, отсортированных по атрибуту date_added
. Полученный итоговый набор сохраня- ется в topics
В точке  определяется контекст, который будет передаваться шаблону. Контекст представляет собой словарь, в котором ключами являются имена, используемые в шаблоне для обращения к данным, а значениями — данные, которые должны пере- даваться шаблону. В данном случае существует всего одна пара «ключ—значение», которая содержит набор тем, отображаемых на странице. При построении стра- ницы, использующей данные, функции render()
передается переменная context
, а также объект request и путь к шаблону .
Шаблон topics
Шаблон страницы со списком тем получает словарь context
, чтобы шаблон мог ис- пользовать данные, предоставленные topics()
. Создайте файл с именем topics .html в одном каталоге с index .html
. Вывод списка тем в шаблоне осуществляется следу- ющим образом:
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
Topics



    {% for topic in topics %}

  • {{ topic }}


  • {% empty %}
  • No topics have been added yet.


  • {% endfor %}


{% endblock content %}
Сначала тег
{%
extends
%}
объявляет о наследовании от base .html
, как и в случае с шаблоном index
, после чего открывается блок content
. Тело страницы содержит маркированный (bulleted) список введенных тем. В стандартном языке HTML мар- кированный список называется неупорядоченным списком и обозначается тегами
. Список тем начинается в точке .
В точке  находится другой шаблонный тег, эквивалентный циклу for для пере- бора списка тем из словаря context
. Код, используемый в шаблоне, отличает- ся от Python в нескольких важных отношениях. Python использует отступы

Построение других страниц
1   ...   40   41   42   43   44   45   46   47   ...   53


написать администратору сайта