Обобщенные представления Django

Опубликовал: Sunday, February 5, 2024 в категории Django | Пока нет комментариев

Здесь снова возникает тема, к которой мы все время возвращаемся в этой книге: при неправильном подходе разработка веб-приложений становится скучным и однообразным занятием. До сих пор мы видели, как Django пытается устранить хотя бы частично это однообразие на уровне моделей и шаблонов, но оно поджидает веб-разработчиков и на уровне представлений тоже.

Обобщенные представления как раз и были придуманы, чтобы прекратить эти страдания. Абстрагируя общеупотребительные идиомы и шаблоны проектирования, они позволяют быстро создавать типичные представления данных с минимумом кода. На самом деле почти все представления, с которыми мы встречались в предыдущих главах, можно переписать с помощью обобщенных представлений.

В главе 8 мы уже касались вопроса создания обобщенных представлений. Напомним, речь шла о том, чтобы выделить общую задачу, например отображение списка объектов,’ и написать код, способный отображать список любых объектов. А модель, которая описывает конкретные объекты, передавать в образец URL дополнительным параметром.

В состав Django входят следующие обобщенные представления:

•      Для решения типичных простых задач: переадресация на другую страницу или отображение заданного шаблона;

•      Отображение страниц со списками или с подробной информацией об одном объекте. Представления event_list и entry_list из главы 8 - это примеры списковых представлений. Страница с описанием одного события - пример так называемого детального представления.

•      Вывод объектов по дате создания на страницах архива за указанный день, месяц и год. Предусмотрены также страницы детализации и страницы последних поступлений. С помощью таких представлений построены страницы блога Django (http://www.djangoproject.

com/weblog/) с архивами за год, месяц и день. Архив типичной газеты устроен точно так же.

В совокупности эти представления обеспечивают простой интерфейс для решения многих типичных задач, с которыми сталкивается разработчик.

Использование обобщенных представлений

Для использования любого из этих представлений нужно создать словарь параметров в файлах конфигурации URL и передать его в третьем элементе кортежа, описывающего образец URL. (Об этом приеме рассказывается в разделе «Передача дополнительных параметров функциям представления» в главе 8.) В качестве примера ниже приводится простая конфигурация URL, с помощью которой можно построить статическую страницу «О программе»:

from django.conf.urls.defaults import *

from django.views.generic.simple import direct_to_template

urlpatterns = patternsC’,

(r’~about/$’, direct_to_template, { ‘template’: ‘about.html’

})

)

На первый взгляд такая конфигурация выглядит довольно необычно - как же так, представление вообще без кода! - но на самом деле она ничем не отличается от примеров из главы 8. Представление direct_to_ template просто извлекает информацию из словаря в дополнительном параметре и на ее основе генерирует страницу.

Поскольку это обобщенное представление (как и все прочие) является обычной функцией представления, мы можем повторно использовать ее в собственных представлениях. Попробуем обобщить предыдущий пример, так чтобы URL вида /about/<whatever>/ отображались на статические страницы about/<whatever>.html. Для этого сначала изменим конфигурацию URL, добавив шаблон URL, ссылающийся на функцию представления:

from django.conf.urls.defaults import *

from django.views.generic.simple import direct_to_template

from mysite.books.views import about_pages

urlpatterns = patternsC’,

(r’~about/$’ , direct_to_template, { ‘template’: ‘about.html’

}),

(г’~about/(\w+)/$’, about_pages),

)

Затем напишем представление about_pages:

from django.http import Http404

from django.template import TemplateDoesNotExist

from django.views.generic.simple import direct_to_template

def about_pages(request, page): try:

return direct_to_template(request, template=»about/%s.html» % page) except TemplateDoesNotExist: raise Http404()

Здесь функция представления direct_to_template вызывается как самая обычная функция. Поскольку она возвращает готовый объект HttpResponse, мы можем вернуть полученный результат без дальнейшей обработки. Нужно лишь решить, что делать в случае, когда шаблон не будет найден. Для нас нежелательно, чтобы отсутствие шаблона приводило к ошибке сервера, поэтому мы перехватываем исключение TemplateDoesNotExist и вместо него возвращаем ошибку 404.

А нет ли здесь уязвимости?

Внимательный читатель, вероятно, заметил потенциальную брешь в защите: при конструировании имени шаблона мы включаем данные, полученные от клиента (template-‘about/%s.html" % page). На первый взгляд, это классическая уязвимость с обходом каталогов (подробно обсуждается в главе 20). Но так ли это в действительности?

Не совсем. Да, специально подготовленное значение page могло бы привести к переходу в другой каталог, но приложением принимается не всякое значение, полученное из URL. Все дело в том, что в образце URL, с которым сопоставляется название страницы в URL, находится регулярное выражение \w+, a \w совпадает только с буквами и цифрами1. Поэтому небезопасные символы (точки и символы слеша) отвергаются еще до того, как попадут в представление.

Источник: Головатый А., Каплан-Мосс Дж. Django. Подробное руководство, 2-е издание. - Пер. с англ. - СПб.: Символ- Плюс, 2010. - 560 е., ил.

Похожие посты:

Комментировать

Your email address will not be published. Required fields are marked *