"Тачка на прокачку" уже давно не выходит. А вот "Django на прокачку" снова продолжает вас радовать. В сегодняшнем эпизоде мы:

1.       Узнаем, что такое препроцессоры и чем они интереснее обычного CSS;

2.       Разберёмся с SASS и SCSS, узнаем, чем они отличаются;

3.       И рассмотрим на практике, как использовать SASS/SCSS в Django-проекте.

Как обычно, меньше болтовни – больше кода. Центрирует картинку Макс. Выходит за рамки Егор. Статью написали авторы канала PyLounge. Поехали!

Постоянная рубрика «В паре слов про».

Препроцессор CSS – это как бы «язык», который добавляет некоторых функций в CSS и при этом не парится о совместимости с браузером. Например, можно использовать переменные, простую программную логику, функции и т.д. Также препроцессоры помогают сделать CSS более кратким, адаптируемым, интуитивным, модным и молодежным.

Существует множество CSS-препроцессоров, но больше всего на слуху SASS/SCSS и LESS.

LESS – это надстройка над CSS, которая добавляет много динамических свойств. Вводит переменные, операции, function-like элементы и примеси, а также возможность писать таблицы стилей модульно.

SASS – это скриптовый язык препроцессора, который интерпретируется или компилируется в каскадные таблицы стилей CSS. Является сокращенным вариантом CSS, однако предоставляет расширенные возможности: переменные, примеси, расширения и импорты.

У SASS есть два синтаксиса, первый это стандартный который был изначально и второй, который был создан под влиянием LESS, и называется SCSS.

Что LESS, что SASS – это примочки чисто для программиста. Потом все равно их код компилируется в обычный CSS.

Как по мне SASS, а точнее SCSS немного проще и синтаксис требует меньше кода. Поэтому будем подключать его.

А вообще, изучить любой препроцессор не так уж сложно, если ты знаешь CSS.

С понятийным аппаратом разобрались. Переходим к практике.

Для начала, создадим пустой Django проект, который я назову django_sass. Для этого:

1.     Открываем командную строку;

2.     Командой mkdir создадим на диске папку django_sass;

3.     И перейдем в нее через cd;

4.     Теперь создадим виртуальное окружение python с помощью инструмента venv;

5.     И сразу же его активируем. Называться наше виртуальное окружение будет env;

mkdir D:\django_sass
cd /d D:\django_sass
python -m venv env
.\env\Scripts\activate

С помощью стандартного пакетного менеджера pip установим в виртуальное окружение нужные для проекта библиотеки. А именно:

1.     сам фреймворк Django,

2.     libsass – модуль-обертку для библиотеки LibSASS, которая на самом деле написана на С++;

3.     django-compressor – он обрабатывает и сжимает подключенные inline Javascript и CSS в шаблоне Django в кэшируемые статические файлы. Также работает LESS и SASS.

Вот пример из документации. В данном случае он нам не особо нужен, так как у нас минимально возможный проект для примера, в котором будет один sass-файл. Но в реальности css и js файлов много, а значит эта штука полезна. Поэтому не упомянуть я ее не мог.

Использование django-compressor: https://django-compressor.readthedocs.io/en/stable/usage.html
Использование django-compressor: https://django-compressor.readthedocs.io/en/stable/usage.html

4.     django-sass-processor – позволяет компилировать SASS/SCSS файлы и использовать их внутри джангового шаблонизатора, с помощью специальных тегов. Дальше я еще обращу ваше внимание на это.

python -m pip install django
python -m pip install libsass django-compressor django-sass-processor

После того, как все установилось:

1.     Создаем Django-проект через django-admin;

2.     Переходим в свежесозданную папку;

3.     И создаем приложение внутри проекта.

django-admin startproject django_sass
cd django_sass
python manage.py startapp test_sass

Надо подключить созданное приложение и установленные библиотеки к Django-проекту, поэтому:

1.     Открываем файл settings.py в корне проекта;

2.     И добавляем пару срок, а именно – в конец массива INSTALLED_APPS название нашего приложения test_sass и библиотеку sass_processor.

Файл settings.py
Файл settings.py

Django-sass-processor поставляется со встроенным поисковиком статических файлов, чтобы находить скомпилированные CSS-файлы. Поэтому нам этот поисковик надо включить, вместе со статическими средствами поиска файлов Django по умолчанию. Чуточку ниже добавим вот такие строки:

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'sass_processor.finders.CssFinder',
]
Всё ещё файл settings.py
Всё ещё файл settings.py

Когда мы обычно настраиваем статические файлы (например CSS, JS файлы) с помощью Django, нам нужно определить наш каталог STATIC_ROOT, в котором будут находиться статические ресурсы. Этот параметр также сообщает Django, где искать эти статические ресурсы. Поэтому нам по аналогии надо определить SASS_PROCESSOR_ROOT, чтобы Django знал, где лежат наши SASS’ы:

Засунем их в тот же каталог, куда обычно добавляют обычные CSS и JS файлы, в папку static в корне проекта. Может было бы и лучше создать отдельный каталог для SASS и SCSS и установить SASS_PROCESSOR_ROOT в этот каталог. Но мне пофигу, я рокстар (извините).

HTML-странички Django проекта принято размещать в папке templates, которую мы создадим чуть позже. Но в настройках укажем сразу. А конкретно укажем, что каталог templates в корне проекта будет использоваться в качестве хранилища шаблонов django. Понадобится нам переменная TEMPLATE_DIR и список TEMPLATES.

TEMPLATE_DIR = os.path.join(BASE_DIR, "templates")

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEMPLATE_DIR,],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Вот теперь создаём папку static в корне проекта. И заодно папку templates, там же в корне. В папку templates добавляем пока что пустой файл index.html.

Структура проекта
Структура проекта

Мы хотим, чтобы наша страничка с подключенным SASS была доступна по адресу 127.0.0.1:8000/sass_page. Поэтому:

1.     Перейдем в файл приложения urls.py;

2.     И пропишем нашему приложению адрес-маршрут;

3.     Если пользователь перейдет по нему, то вызовется функция-обработчик sass_page_handler, которую создадим немного дальше.

from django.contrib import admin
from django.urls import path
from test_sass import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('sass_page', views.sass_page_handler),
]

Теперь самое время создать эту функцию-обработчик. Для этого:

1.     Переходим в папку приложения test_sass;

2.     И открываем файл views.py;

3.     Здесь мы и создадим функцию sass_page_handler, которая будет просто отдавать браузеру нашу index.html страницу, на которой мы подключим SASS.

from django.shortcuts import render

# Create your views here.
def sass_page_handler(request):
    return render(request, 'index.html')

Наконец:

1.     Отправляемся в созданную ранее папку static;

2.     В ней создадим папку css;

3.     А в этой папке и сам SASS-файл main.scss.

4.     Далее в этот файл запишем какой-нибудь простенький стиль. Например, текст внутри всех h1 тегов, которые лежат внутри тега body будет 20px, по центру и красный;

body {
    h1 {
    font-size: 20px;
    text-align: center;
	color:red;
	}
}

Теперь же отправляемся в файл index.html. Добавим туда минимальную разметку и подключим main.sсss файл:

1.     Первоначально добавляем шаблонный тег load sass_tags, который дает возможность подключить SCSS-файлы к нашему шаблону страницы;

2.     Затем в link, также с помощью специального тега sass_src, доступного благодаря библиотеке django-sass-processor, указываем путь до main.sсss файла и подключаем его;

3.     Ну и немного простенькой html-разметки для вида.

{% load sass_tags %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="{% sass_src 'css/main.scss' %}" rel="stylesheet" type="text/css"/>
        <title>Django Sass</title>
    </head>
    <body>
        <h1>Эта страница со стилями SASS/SCSS, базарю</h1>
    </body>
<html>

Возвращаемся в консоль и запускам наш django-проект командой python manager.py runserver.

Теперь:

1.     Откроем браузер;

2.     И введем в адресную строку 127.0.0.1:8000/sass_page

3.     Все работает.

Все, SCSS нормально функционирует на странице, а вы великолепны!


Исходный код:https://github.com/pylounge/pylounge-django-sass

Если кому-то проще в видеоформате:

Комментарии (2)


  1. baldr
    21.01.2023 10:38
    +5

    То есть у вас SCSS файлы компилируются каждый раз при рендеринге страницы? И еще и сжимаются? Но это же неэффективно? Оно, вроде бы, говорит о кэшировании, но тем не менее.. Если у нас больше одной ноды (за Load Balancer), то имена файлов в кэше будут разные и пользователь может несколько раз качать, по факту, один и тот же css-файл. А как быть с зависимостями от внешних css/js библиотек?

    У меня уже лет 7 приготовлен и настроен шаблон для джанго-проектов с Gulp-тасками, которые перед публикацией на продакшен в докер-контейнере собирают все js-зависимости из npm, компилируют мои SCSS, coffeescript (да, я его использую), конвертируют картинки и сжимают всю статику. В итоге получаем чистые css/js файлы, которые django даже не трогает - их раздает сразу nginx.

    В целом идея хорошая и использовать препроцессоры можно и нужно, но я бы, по возможности, выносил сборку статики отдельно.


  1. dmi3mart
    21.01.2023 13:44
    +4

    Компиляцией SASS в CSS должен заниматься не Джанго, а бандлер на стороне фронтенда: Webpack или Vite. Даже в "монолитных" приложениях. То, что вы описали в статье - оверкилл и анти-практика.