Кодирование ссылок в шаблоне

Кодирование ссылок — это та проблема, которая хорошо умеет скрываться. Её сложно заметить, до поры до времени вы о ней даже на задумываетесь. А потом случайно узнаёте о том, что сайт сломан. Сломан он вот уже как полгода. Часть его страниц просто не работают. Пускай вы даже всё тестировали и всё проверяли, но они сломались, внезапно и незаметно.

Если о кодировании ссылок вы слышите впервые, то сначала познакомьтесь с проблемой:

Как тестировать

Самая большая проблема — это тестирование. Что не видно — то сложно чинить.

Если вы работаете с шаблонами, то есть такой способ. Проделать его надо с каждой подстановкой адреса. Прямо в шаблоне подмените переменную {{ some_var }} на строку с зашитым в неё адресом. Выглядеть будет примерно так:

{{ 'http://...some-url...' }}

Если не хотите трогать шаблон, то сделайте то же самое внутри Python скрипта перед отправкой данных в шаблон.

Теперь подмените символы в адресе на заведомо запрещённые. Если то была картинка photo.png, то пусть станет фото с котиком.png. Если GET параметр, то пусть тоже получит вымышленное значение с пробелами и кириллицой. Не важно существует такой адрес или нет, просто проверьте итоговую HTML разметку, на глаз или через W3C Validator.

Кодируйте каждую динамическую ссылку

В шаблоне не должно быть путей:

<img src="{{ photo_path }}" alt="котик"/>

Так тоже опасно:

<img src="images/{{ photo }}" alt="котик"/>

Не должно быть в шаблоне и GET параметров:

<a href="./search?q={{ text }}">...</a>

Во всех этих случаях необходимо кодирование. На стороне Python это делается с помощью urllib.parse.quote и urllib.parse.urlencode. В шаблонах Django и Jinja2 — с помощью шаблонного фильтра urlencode.

Исключения из правил:

  • Слаги (slug) — это фрагмент адреса с ограниченным набором символов. Всё, что разрешено в слаге можно использовать и в url. What is slug?.
  • Шаблонные теги {% url ... %}, {% static ... %} в Django. Они сами кодируют url.

Если ваш случай здесь рассмотрен не был, и вы не уверены в кодировании ссылок, то обязательно выясните это. Не ленитесь, протестируйте. Поставьте любое значение с запрещёнными символами — пробелами, кириллицей — и проверьте какой адрес получится в итоге.


Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.