Как создать пользовательский CSS "на лету" на основе настроек учетной записи на сайте Django?

Итак, я пишу сайт на основе Django, который позволяет пользователям выбирать цветовую схему через интерфейс администрирования.

У меня уже есть промежуточные/контекстные процессоры, которые связывают текущий запрос (на основе домена) с учетной записью.

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

Я вижу два варианта:

  • Добавить блок CSS в базовый шаблон, который переопределяет стили w/variables, передаваемые через контекстные процессоры.

  • Используйте настраиваемый URL (например, "/static/dynamic/css/< website_id > /styles.css" ), который перенаправляется в представление, которое захватывает все необходимые значения и создает файл css.

Я согласен с любым вариантом, но мне было интересно, есть ли у кого-то еще проблемы с подобными проблемами и может дать некоторое представление о "лучших практиках".

Обновление. Я склоняюсь к варианту номер 2, так как я думаю, что это позволит лучше кэшировать дорогу. Таким образом, он динамический в первый раз, хранится в memcache (или что-то еще) и недействителен, когда пользователь обновляет свои настройки на сайте администратора.

Обновление. Во-первых, я хотел бы поблагодарить всех за их предложения. Все ответы до сих пор были сосредоточены на создании статических файлов. Хотя это будет отлично работать в производстве, оно ощущается как огромное бремя во время развития. Если бы я хотел добавить новый элемент в стиле или изменить существующие стили, мне пришлось бы пройти и воссоздать каждый файл css. Конечно, это можно сделать с помощью команды управления, но я просто не считаю, что это того стоит. Выполняя его динамически, вы добавили бы 1, возможно, 2 запроса к каждой загрузке страницы, на что я не беспокоюсь на этом этапе. Все, что мне нужно знать, это то, что в какой-то момент я смогу кэшировать его, не переписывая все это.

Ответ 1

Я успешно использовал вариант №2. Есть два достойных способа обновления созданных статических файлов, о которых я знаю:

  • Используйте версию запроса, например /special _path.css?v=11452354234, где параметр v создается из поля базы данных, ключа в memcached или какого-либо другого постоянного файла. Версия обновляется администратором, или для разработки вы просто должны заставить генерацию не сохранять, если параметр был чем-то особенным, например v = -1. Вам понадобится процесс для очистки старых поколений через некоторое время.

  • Не используйте верификацию версии, но сначала посмотрите на сгенерированный файл, если он не может найти его, он генерирует его. Вы можете создать задание cron или приложение WSGI, которое ищет изменения в файловой системе для разработки, и у вас есть крючок с панели администратора, которая удаляет поколения после обновления. Вот пример мониторинга, который вам нужно будет преобразовать, чтобы быть конкретным для ваших поколений, а не для Django. http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring%5FFor%5FCode%5FChanges

Ответ 2

Хороший вопрос.

Я бы предложил предварительно создать файл css после сохранения схемы цветов. Это окажет положительное влияние на кеширование и общее время загрузки страницы. Вы можете хранить ваши файлы css в каталоге /media/css/custom/<id or stometing>/styles.css или /media/css/custom/<id or sth>.css, а в шаблоне добавить <link rel="stylesheet" href="/media/css/custom/{{some_var_pointing _to_file_name}}" />

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

UPDATE: пример использования модели для улучшения этого примера Чтобы упростить управление этими файлами, вы можете создать простую модель (по одному на каждого пользователя):

class UserCSS(models.Model):
    bg_color = models.CharField(..)
    ...
    ...

Поля (например, bg_color) могут представлять части вашего файла css. Вы можете ovveride save метод добавить логику, которая создает файл css для пользователя (путем рендеринга некоторого шаблона).

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

Это должно хорошо работать.

Ответ 3

Может генерировать css и хранить его в текстовом поле в той же модели, что и профиль пользователя/настройки. Тогда вы можете создать их, если вы измените стиль. Затем сделайте свой вариант 1 выше.

Ответ 4

Я бы создал ключ md5 с элементами темы, сохранил этот ключ в профиле пользователя и создал ccs файл с именем после этого ключа md5: вы получаете статический доступ к файлам и автоматическое обнаружение изменений темы.