Search code examples
pythondjangocollectstatic

Example for customizing the ignored pattern list in Django's collectstatic


Like other questions here, I want to ignore my .scss files when running collectstatic. But because I'm using Heroku, which runs a collectstatic automatically, I would rather customize collectstatic's ignore pattern list rather than change the management command.

Django 2.2 provides a way to do this, as documented below:

The default ignored pattern list, ['CVS', '.', '~'], can be customized in a more persistent way than providing the --ignore command option at each collectstatic invocation. Provide a custom AppConfig class, override the ignore_patterns attribute of this class and replace 'django.contrib.staticfiles' with that class path in your INSTALLED_APPS setting:

from django.contrib.staticfiles.apps import StaticFilesConfig

class MyStaticFilesConfig(StaticFilesConfig):
    ignore_patterns = [...]  # your custom ignore list

My problem is that, this being my first Django project, I don't quite know how to provide a custom AppConfig class (and diving into the AppConfig docs hasn't helped). I mean, should I add this class to a whole new app or use an existing one? Is this class going to be in a apps.py file? If so, what should be the best app to do so? So I'm asking if anyone could provide me with an example of the best practice.

For reference, right now my app structure is like this (with all templates, assets and apps grouped together in their own folders rather than within each app):

-- project_name
  -- assets
    -- app1
  -- templates
  -- project_name
    -- app1
    -- app2
    -- __init__.py
    -- settings.py
    -- urls.py
    -- wsgi.py

UPDATE: As Nico suggested, I've created an app called static in project_name.project_name with only an init.py file and an apps.py. The apps.py is exactly like the doc example:

from django.contrib.staticfiles.apps import StaticFilesConfig

class StaticConfig(StaticFilesConfig):
    name = 'static'
    ignore_patterns = ['CVS', '.*', '*~', '*.scss'] 

However, I'm running into errors when replacing 'django.contrib.staticfiles' from INSTALLED_APPS.

  • Replacing it for 'project_name.static' makes the terminal not understand the collectstatic management command.
  • Adding 'project_name' after 'django.contrib.staticfiles' (i.e. not removing the later) makes it ignore the overwrite and collect the .scss files.
  • Replacing for 'project_name.static.apps.StaticConfig' throws a Cannot import 'static'. error

UPDATE 2: After I rollbacked the app creation, I tried is again, but now, instead of using the startapp with the file path, I created the app on the project root, tested it, then moved it manually to my apps' folders, and tested it again. For some reason I don't quite understand, this time I replaced 'django.contrib.staticfiles' for 'project_name.static' and now it worked.


Solution

  • You can add it to some other app, or even create just a file called static in the root of project_name and refer to the class inside this file in your settings.INSTALLED_APPS directly, but the recommended way to provide AppConfigs is inside an apps.py file inside the application package.

    If you have no app where this AppConfig could be placed, I think the best practice would be to create a package under project_name.project_name called static, with only an init.py file and an apps.py file.

    In this file you can create your AppConfig in the way you described. Your file structure will then look like this:

    -- project_name
      -- assets
        -- app1
      -- templates
      -- project_name
        -- app1
        -- app2
        -- static
           -- __init__.py
           -- apps.py
        -- __init__.py
        -- settings.py
        -- urls.py
        -- wsgi.py