0

I really like django-pipeline but I wish to set my assets inside each app. It's cleaner and don't mess with the settings.py. So In the __init__.py of a "core" app I have the code below.

# __init__.py file

from django.conf import settings
from django.utils.importlib import import_module


GLOBAL_PP_JS = {}
GLOBAL_PP_CSS = {}

for app in settings.INSTALLED_APPS:

    try:
        mod = import_module('%s.compressed' % app)
    except:
        continue

    try:
        GLOBAL_PP_JS.update(mod.PIPELINE_JS)
    except:
        pass

    try:
        GLOBAL_PP_CSS.update(mod.PIPELINE_CSS)
    except:
        pass

PIPELINE_JS = setattr(settings, 'PIPELINE_JS', GLOBAL_PP_JS)
PIPELINE_CSS = setattr(settings, 'PIPELINE_CSS', GLOBAL_PP_CSS)

It searches for compressed.py modules in each app.

# compressed.py file

PIPELINE_JS = {
    'js_group': {
        'source_filenames': (
            'js/base.js',
        ),
        'output_filename': 'js/group.js',
    }
}

Well, it isn't working since the settings has security features to prevent overriding its variables.

Can someone point me some Django pattern or any workaround to make this code work?

I'm using Django 1.7 and Django-Pipeline 1.4.3 .

Arthur Alvim
  • 1,044
  • 12
  • 23

1 Answers1

0

Django settings are only write-protected outside the settings file. As long as you don't create circular imports, it is fine to dynamically set PIPELINE_JS and PIPELINE_CSS based on the compressed modules in your installed apps. Obviously, the order matters, and INSTALLED_APPS needs to be complete (or at least include all apps that have a compressed module) before you load the js and css files.

Another way is to use a descriptor object (with __get__ and __set__ methods) as your PIPELINE_JS and PIPELINE_CSS settings, that loads the app-based settings lazily. This will ensure that all INSTALLED_APPS are available.

knbk
  • 52,111
  • 9
  • 124
  • 122