Создать URL
Генератор Правила транслитерации Как сделать ЧПУ Транслит для загранпаспорта ГОСТ 7.79 ISO 9 Блог Вопросы и ответы Создать URL
Транслитерация

Django: slugify и русские заголовки, готовая функция транслита

Стандартный slugify Django рассчитан на ASCII: для русского заголовка он вернёт пустую строку. Разберём, почему так происходит и как получить нормальный slug.

В чём проблема

По логике реализации slugify, при allow_unicode=False текст нормализуется и кодируется в ASCII с отбрасыванием символов, которых там нет. Кириллица в ASCII отсутствует, поэтому русские буквы пропадают. Для заголовка «Привет мир» результат — пустая строка.

Параметр allow_unicode

С allow_unicode=True русские буквы остаются в slug. Это решает проблему пустого значения, но адрес остаётся кириллическим. Если нужна латиница, потребуется транслитерация. Шаблонный фильтр slugify параметр allow_unicode не принимает (запрос на это закрыт: предлагается написать свой фильтр).

Готовая функция по таблице Яндекса

Функция работает по таблице генератора. Её можно подключить в методе save() модели или в pre_save:

import re

YANDEX = {
    'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e',
    'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k',
    'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r',
    'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', 'х': 'h', 'ц': 'c',
    'ч': 'ch', 'ш': 'sh', 'щ': 'shh', 'ъ': '', 'ы': 'y', 'ь': '',
    'э': 'e', 'ю': 'yu', 'я': 'ya',
}


def yandex_slug(text):
    out = "".join(YANDEX.get(ch, ch) for ch in text.lower())
    out = re.sub(r"[^a-z0-9]+", "-", out)
    return out.strip("-")

Для «Щёлково цех юг» функция даёт shhelkovo-ceh-yug, как и генератор.

Не забывайте про уникальность

Если два заголовка дадут один slug, поле с ограничением unique вызовет ошибку. Добавляйте суффикс при совпадении: «Генерация уникального слага при коллизиях». Особенно важно, если slug может получиться пустым.

Связанные статьи

Маршруты со слагами в Django — в статье «Роутинг в Django: слаги и уникальность».

Источники

Описание основано на обсуждении в трекере Django и коде функции. Проверьте поведение на вашей версии.

Типичные ошибки

  • Использовать slugify без allow_unicode для русских заголовков.
  • Хранить пустой slug: он ломает уникальность.
  • Использовать allow_unicode и ожидать латиницу.
  • Менять slug опубликованной записи без редиректа.

Пошагово: приводим адреса к единому виду

  1. Найдите в проекте модели, где slug создаётся из заголовка.
  2. Подключите функцию yandex_slug вместо slugify.
  3. Добавьте проверку уникальности.
  4. Для существующих записей пересчитайте slug одной командой управления.
  5. Для опубликованных записей настройте редиректы.

Разбор заголовка по шагам

Возьмём заголовок «Как выбрать беговые кроссовки» и пройдём путь до адреса. Функция превращает заголовок в slug при сохранении модели.

Заголовок:           Как выбрать беговые кроссовки
Без служебных слов:  Как выбрать беговые кроссовки
Адрес целиком:       kak-vybrat-begovye-krossovki
Адрес короче:        kak-vybrat-begovye-krossovki

Режим «Убрать служебные слова» в генераторе делает второй шаг сам. Короткий адрес читается легче и лучше помещается в строку браузера. Ограничения по длине и другие правила составления адреса собраны в статье «Как составить ЧПУ-адрес страницы».

Памятка для редактора

Если в проекте несколько редакторов, дайте им короткую памятку. Достаточно этих правил:

  • Свою функцию — для русских заголовков.
  • Проверяем уникальность и пустое значение.
  • Меняем slug — с редиректом.

Чек-лист

  1. Не использовать slugify без allow_unicode для русского.
  2. Подключить функцию в save().
  3. Проверять уникальность.
  4. При смене slug настраивать редирект.

Частые вопросы

Почему slugify возвращает пустую строку для русского заголовка?

В режиме по умолчанию он оставляет только ASCII-символы, а кириллицы там нет.

Что делает allow_unicode=True?

Оставляет русские буквы в slug: адрес получается кириллическим.

Как получить латинский slug?

Написать функцию транслитерации и вызвать её в save() модели.

Что делать при совпадении slug?

Добавлять суффикс и проверять уникальность перед сохранением.

Проверьте свои заголовки: вставьте их в генератор ЧПУ и посмотрите, как в адресе выглядят слова с этой буквой.

Читайте также