diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df8b601..54587e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] - django-version: ["2.2", "3.2", "4.0"] + django-version: ["3.2", "4.0", "4.1", "4.2"] exclude: - python-version: 3.9 django-version: 2.2 @@ -21,6 +21,10 @@ jobs: django-version: 2.2 - python-version: 3.7 django-version: 4.0 + - python-version: 3.7 + django-version: 4.1 + - python-version: 3.7 + django-version: 4.2 steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index 778b3da..5e4cb94 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,8 @@ INSTALLED_APPS = [ ``` **django-sass-processor** is shipped with a special finder, to locate the generated `*.css` files -in the directory referred by `SASS_PROCESSOR_ROOT` (or, if unset `STATIC_ROOT`). Just add it to +in the directory referred by `STORAGES['sass_processor']['ROOT']` (for Django >= 4.2.*) or +`SASS_PROCESSOR_ROOT` (for Django <= 4.1.*), or, if unset `STATIC_ROOT`. Just add it to your `settings.py`. If there is no `STATICFILES_FINDERS` in your `settings.py` don't forget to include the **Django** [default finders](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-STATICFILES_FINDERS). @@ -129,7 +130,8 @@ letter or number are intended to be included by the HTML tag ``. During development, or when `SASS_PROCESSOR_ENABLED = True`, the compiled file is placed into the -folder referenced by `SASS_PROCESSOR_ROOT` (if unset, this setting defaults to `STATIC_ROOT`). +folder referenced by `STORAGES['sass_processor']['ROOT']` (for Django >= 4.2.*) or `SASS_PROCESSOR_ROOT` (for Django <= 4.1.*). +If unset, this setting defaults to `STATIC_ROOT`. Having a location outside of the working directory prevents to pollute your local `static/css/...` directories with auto-generated files. Therefore assure, that this directory is writable by the Django runserver. @@ -311,7 +313,8 @@ above command: This will remove all occurrences of previously generated `*.css` files. -Or you may compile results to the `SASS_PROCESSOR_ROOT` directory directy (if not specified - to +Or you may compile results to the `STORAGES['sass_processor']['ROOT']` [Django >= 4.2.*] or `SASS_PROCESSOR_ROOT` +[Django <= 4.1.*] directory directy (if not specified - to `STATIC_ROOT`): ```shell @@ -424,17 +427,27 @@ to the Django logger. ## Using other storage backends for compiled CSS files -Under the hood, SASS processor will use any storage configured in your settings as `STATICFILES_STORAGE`. +Under the hood, SASS processor will use any storage configured in your settings as `STORAGES['staticfiles']`. This means you can use anything you normally use for serving static files, e.g. S3. A custom Storage class can be used if your deployment needs to serve generated CSS files from elsewhere, e.g. when your static files storage is not writable at runtime and you nede to re-compile CSS -in production. To use a custom storage, configure it in `SASS_PROCESSOR_STORAGE`. You can also +in production. To use a custom storage, configure it in `STORAGES['sass_processor']['BACKEND']`. You can also configure a dictionary with options that will be passed to the storage class as keyword arguments -in `SASS_PROCESSOR_STORAGE_OPTIONS` (e.g. if you want to use `FileSystemStorage`, but with -a different `location` or `base_url`: +in `STORAGES['sass_processor']['OPTIONS']` [Django >= 4.2.*] or `SASS_PROCESSOR_STORAGE_OPTIONS` [Django <= 4.1.*>] +(e.g. if you want to use `FileSystemStorage`, but with a different `location` or `base_url`: ```python +# For Django >= 4.2.* +STORAGES['sass_processor'] = { + 'BACKEND': 'django.core.files.storage.FileSystemStorage', + 'OPTIONS': { + 'location': '/srv/media/generated', + 'base_url': 'https://media.myapp.example.com/generated' + } +} + +# For Django <= 4.1.* SASS_PROCESSOR_STORAGE = 'django.core.files.storage.FileSystemStorage' SASS_PROCESSOR_STORAGE_OPTIONS = { 'location': '/srv/media/generated', @@ -449,6 +462,12 @@ Using the S3 storage backend from [django-storages](https://django-storages.read with its regular configuration (if you do not otherwise use it for service static files): ```python +# For Django >= 4.2.* +STORAGES['sass_processor'] = { + 'BACKEND': 'storages.backends.s3boto3.S3Boto3Storage' +} + +# For Django <= 4.1.* SASS_PROCESSOR_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' ``` diff --git a/sass_processor/storage.py b/sass_processor/storage.py index 8c13def..0adbf85 100644 --- a/sass_processor/storage.py +++ b/sass_processor/storage.py @@ -1,17 +1,31 @@ +from django import VERSION from django.conf import settings from django.contrib.staticfiles.finders import get_finders from django.core.files.storage import FileSystemStorage, get_storage_class from django.utils.functional import LazyObject +from django.utils.module_loading import import_string class SassFileStorage(LazyObject): def _setup(self): - storage_path = getattr(settings, 'SASS_PROCESSOR_STORAGE', settings.STATICFILES_STORAGE) - storage_options = getattr(settings, 'SASS_PROCESSOR_STORAGE_OPTIONS', {}) - storage_class = get_storage_class(storage_path) + version_parts = VERSION[:2] + if version_parts[0] > 4 or (version_parts[0] == 4 and version_parts[1] >= 2): + staticfiles_storage_backend = settings.STORAGES.get("staticfiles", {}).get("BACKEND") + sass_processor_storage = settings.STORAGES.get("sass_processor", {}) - if storage_path == settings.STATICFILES_STORAGE and issubclass(storage_class, FileSystemStorage): - storage_options['location'] = getattr(settings, 'SASS_PROCESSOR_ROOT', settings.STATIC_ROOT) + storage_path = sass_processor_storage.get("BACKEND") or staticfiles_storage_backend + storage_options = sass_processor_storage.get("OPTIONS") or {} + storage_class = import_string(storage_path) + else: + staticfiles_storage_backend = settings.STATICFILES_STORAGE + storage_path = getattr(settings, 'SASS_PROCESSOR_STORAGE', staticfiles_storage_backend) + storage_options = getattr(settings, 'SASS_PROCESSOR_STORAGE_OPTIONS', {}) + storage_class = get_storage_class(storage_path) + + storage_options["ROOT"] = getattr(settings, 'SASS_PROCESSOR_ROOT', settings.STATIC_ROOT) + + if storage_path == staticfiles_storage_backend and issubclass(storage_class, FileSystemStorage): + storage_options['location'] = storage_options.pop("ROOT", None) or settings.STATIC_ROOT storage_options['base_url'] = settings.STATIC_URL self._wrapped = storage_class(**storage_options) diff --git a/setup.cfg b/setup.cfg index ca7c44d..86e8f40 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,9 +23,10 @@ classifiers = Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 - Framework :: Django :: 2.2 Framework :: Django :: 3.2 Framework :: Django :: 4.0 + Framework :: Django :: 4.1 + Framework :: Django :: 4.2 [options] packages = find: