Django-кнопка «Наверх»: подключить за минуту вместо очередного велосипеда
Кнопка «Наверх» — вещь настолько простая, что обычно её делают прямо в проекте: ссылка, немного CSS, пара строк JavaScript — готово.
Для одной страницы это нормально. Но потом проект растёт. Появляется мобильная версия, cookie-баннер, чат в углу, требования к контрасту, строгий CSP. Где-то нужно добавить кнопку ещё и в Django Admin. И тот самый маленький кусок кода начинает жить своей жизнью.
Такой модуль нужен давно: кнопка «Наверх» встречается на множестве сайтов, но в Django-проектах её по-прежнему часто собирают вручную — каждый раз немного по-своему.
Мне хотелось получить готовое решение: подключил, настроил через админку и больше не возвращаешься к этому коду при каждом новом проекте.
Так появился django-scroll-to-top.

Конечно, для одной страницы можно написать всё вручную — и это будет правильным решением. Пакет нужен в другом случае: когда хочется поставить кнопку один раз, а потом не возвращаться к ней при каждом изменении интерфейса.
Что хотелось получить
Не очередной большой фронтенд-комбайн, а обычный Django-модуль, который:
подключается через один
template tag;работает и на сайте, и в стандартной Django Admin;
настраивается через админку, без правок CSS и JavaScript в проекте;
не тащит jQuery, CDN и обязательную сборку фронтенда;
работает при строгом CSP;
учитывает клавиатуру, фокус, контраст и отключение анимаций;
не прячется под cookie-баннером, чатом или мобильной навигацией.
Пакет пока находится в серии 0.x: его уже можно использовать, но до версии 1.0 отдельные точки интеграции ещё могут меняться. Поддерживаются Python 3.10+ и Django 4.2 LTS, 5.x и 6.0.
Подключение
В обычном случае нужно установить пакет:
python -m pip install django-scroll-to-top
Добавить приложение в INSTALLED_APPS:
INSTALLED_APPS = [ # ... "django_scroll_to_top", ]
Если нужна интеграция со стандартной Django Admin, пакет должен стоять перед django.contrib.admin:
INSTALLED_APPS = [ # ... "django_scroll_to_top", "django.contrib.admin", ]
Подключить URLConf:
# urls.py from django.urls import include, path urlpatterns = [ # ... path( "scroll-to-top/", include( ("django_scroll_to_top.urls", "django_scroll_to_top"), namespace="django_scroll_to_top", ), ), ]
Применить миграции:
python manage.py migrate
И добавить тег в общий шаблон:
{% load scroll_to_top %} {# содержимое страницы #} {% scroll_to_top %}
После этого кнопка уже появится на сайте.
Настройки внешнего вида не передаются длинным списком аргументов в шаблоне. Они хранятся в базе и редактируются через Django Admin: можно поменять угол, цвета, размер, иконку, поведение при прокрутке и отдельные параметры для мобильной версии.
Настройка через Django Admin
У кнопки есть две независимые области настроек:
site— страницы сайта;admin— стандартная Django Admin.
То есть в админке можно сделать одну кнопку, а на публичной части сайта — другую. Например, в админке оставить спокойный нейтральный вариант, а на сайте подобрать цвета под оформление проекта.

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

Для кнопки «Наверх» это может показаться избыточным. Но когда внизу страницы появляется баннер, чат или новая мобильная панель, возможность поправить кнопку через админку заметно удобнее, чем искать старый CSS и выпускать изменения только ради отступа.
Иконки: есть готовые, можно загрузить свои
По умолчанию в пакет добавлен небольшой набор иконок из Tabler Icons. Я выбрал его потому, что это аккуратные и узнаваемые SVG-иконки с MIT-лицензией. Они используют currentColor, поэтому нормально подхватывают выбранные цвета кнопки.
В админке можно выбрать стрелку, шеврон, caret и другие привычные обозначения прокрутки вверх.

Но встроенным набором всё не ограничивается. Можно загрузить собственную SVG-иконку через админку: например, если у проекта уже есть фирменный набор иконок или хочется использовать свой знак вместо обычной стрелки.
Загруженная SVG не отдаётся в браузер как есть: перед использованием она проходит проверку и очистку от потенциально опасных конструкций. Для иконки также можно сохранить автора, источник и информацию о лицензии.
То есть для быстрого старта есть готовые варианты, а для проекта со своим оформлением не придётся менять шаблоны или лезть в код пакета.
Что в итоге
django-scroll-to-top не пытается доказать, что кнопка «Наверх» сама по себе сложная задача. В простом проекте её действительно можно сделать вручную за несколько минут.
Но если такая кнопка нужна не один раз, а как нормальный переиспользуемый элемент сайта или админки, удобнее подключить готовый модуль и не держать в каждом проекте свою слегка отличающуюся версию.
В пакете уже есть отдельные настройки для мобильных устройств, варианты оформления, проверка контраста, строгий CSP, безопасная загрузка SVG и обход плавающих виджетов. Это уже тема для следующей статьи. Здесь хотелось показать главное: кнопку можно быстро подключить и не собирать заново в каждом Django-проекте.
Репозиторий: GitHub
Пакет: PyPI
Буду рад отзывам, замечаниям и особенно сообщениям о том, как пакет ведёт себя в проектах с нестандартной Django Admin, сторонними темами, cookie-баннерами и чатами.
Комментарии (9)

Magnat_ts
28.06.2026 15:05А миграция зачем нужна ? Так и не понял

MihailPy
28.06.2026 15:05В статье написано, что настройки кнопки сохраняются в базе. А еще можно настроить на разных страницах, разные кнопки, для этого тоже наверное база данных используется.

krox Автор
28.06.2026 15:05Да, именно для хранения конфигурации.
Миграция создаёт модели для профилей и ревизий настроек: отдельная конфигурация для сайта и Django Admin, черновики, публикация, откат, параметры внешнего вида и поведения, загруженные SVG-иконки.
При подключённом
django.contrib.sitesможно также сделать отдельный профиль для конкретного Site с общей конфигурацией как запасным вариантом.Для простой статичной кнопки это, конечно, избыточно — её проще добавить вручную. Здесь база нужна именно потому, что пакет рассчитан на настраиваемый компонент, который потом можно менять через админку без правок кода.

olegtsss
28.06.2026 15:05Попробовал установить ваш пакет, подскажите, кнопка на сайте появилась, в админке все три секции ее настройки пустые. Ничего не загружено. Что сломалось?

krox Автор
28.06.2026 15:05Первая секция - это для загрузки своих иконок. Вы добавили профили кнопки прокрутки и ревизии кнопки прокрутки? Если нет, вначале создаёте ревизию и цепляете её к профилю. Если остались вопросы - можно в ТГ обсудить или дальше в комментариях

olegtsss
28.06.2026 15:05Я сделал по статье. Добавил код, мигранул, увидел, что кнопка появилась и полез в админку. Там три секции, внутри пусто во всех. Получается профили и ревизии я не делал. Попробую вечером, дам обратную связь.

krox Автор
28.06.2026 15:05Ещё раз у себя проверил. Создаёте ревизию, из него профиль или отдельно. И когда ревизию сохраните, надо будет профиль ещё раз подредактировать и выбрать созданную вами ревизию. Да, немного косячно (ошибки проектирования с ИИ), но работает. Посмотрите пожалуйста, может ещё какие замечания всплывут и в новой версии всё исправлю
Osti-Osti
Необходимость делать миграцию ради кнопки "Наверх" это, конечно, круто!
На мой взгляд, оптимальным решением является создавать кнопку "Наверх" динамически с помощью JavaScript. На крайний случай, код кнопки можно вставить в базовый шаблон.
krox Автор
Согласен: если нужна одна статичная кнопка «Наверх», я бы тоже не стал ставить отдельный пакет с миграциями. Ссылка в базовом шаблоне или небольшой JavaScript здесь проще и правильнее.
Я рассматривал вариант, где всё настраивается только через
settings.pyи миграции не нужны. Но у кнопки довольно быстро набирается много параметров: отдельные настройки для сайта и админки, положение, размеры, мобильные переопределения, цвета и состояния, иконки, порог показа, поведение при прокрутке, столкновения с чатами и баннерами, настройки скрытия пользователем.В итоге получился бы большой словарь в настройках проекта, который всё равно меняется только разработчиком и требует выкладки при каждой правке дизайна.
Поэтому для текущего варианта я выбрал конфигурацию в базе и Django Admin. Миграция делается один раз при установке, зато дальше кнопку можно менять без поиска кода: например, дизайнером или администратором сайта с нужными правами. Это удобно, когда изменили дизайн, добавили чат или cookie-баннер, а разработчик, который когда-то собирал интерфейс, уже не занимается этим проектом.
То есть пакет не пытается заменить пару строк JS в простом случае. Он рассчитан на сценарий, где кнопка становится настраиваемым компонентом сайта.
А вариант облегчённого режима без БД действительно имеет смысл. Если будет спрос на такой способ подключения, его можно сделать отдельным режимом с настройками через
settings.py.