pythondjangodjango-staticfilesdjango-grappelli

Django static files not consistent between DEBUG=True and after `collectstatic`


My "Select all {amount} {model}s" action, which should be in the actions bar while viewing a model page in the Django admin, does not work in production.

Expected behaviour, as recorded running locally with DEBUG=True in local_settings.py: Django footer action bar showing a dropdown, then three buttons; "100 out of 100 selected", "Select all 3000 Films" and "Execute" all translated to Dutch.

Behaviour on staging deployment and while running locally with DEBUG=False: Django footer action bar showing a dropdown, then three buttons; "0 out of 100 selected", then one offset slightly higher saying "100 out of 100 selected" and "Execute". There is no "Select all".

I'm having issues with inconsistency between the static files my templates are working with between a local running of the runserver command with DEBUG=True vs. running the same codebase after running collectstatic and then running it with DEBUG=False in my settings.

The differences in static files is also apparent in the listed sources when inspecting the page. Working correctly:

Filesystem showing the file "actions.js"

Not working correctly:

Filesystem showing the file "actions.min.js"

Running the collectstatic command gives me this output:

Loading .env environment variables...
Found another file with the destination path 'admin/js/actions.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'admin/js/admin/RelatedObjectLookups.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.
Found another file with the destination path 'admin/js/admin/DateTimeShortcuts.js'. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path.

But locally, both actions.js and actions.min.js are present in my static files folder. I don't want to turn on DEBUG on the production deployments, but currently don't know how to solve this issue I'm having. All help would be appreciated.

EDIT: My settings file was requested, so here's a version (cleaned of sensitive data):

import os

DEBUG = False
MAINTENANCE_MODE = False
TEMPLATE_DEBUG = DEBUG
DEPLOYMENT_NAMESPACE = os.getenv("K8_NAMESPACE", "")
DEPLOY_LOCATION = "testing"
SESSION_COOKIE_AGE = 604800  # A week
DATABASES: dict = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "HOST": "127.0.0.1",
        "NAME": f"[DB_NAME]",
        "USER": "postgres",
        "PASSWORD": "[PASSWORD]",
    }
}
DATABASES["readonly"] = DATABASES["default"].copy()
DATABASES["readonly"]["USER"] += "_readonly"
DATABASES["readonly"]["TEST"] = {"MIRROR": "default"}

UNICORN_VERSION = os.getenv("UNICORN_VERSION", "[COMPANY_NAME]")

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = PROJECT_PATH.joinpath("static")

# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = "/static/"

# Additional locations of static files
STATICFILES_DIRS = (
    PROJECT_PATH.joinpath("versions", UNICORN_VERSION, "static"),
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    "django.contrib.staticfiles.finders.FileSystemFinder",
)

LOCALE_PATHS = [PROJECT_PATH.joinpath("locale")]

# When a version defines a locale folder, it becomes the main
LOCALE_PATHS = getattr(version_settings, "LOCALE_PATHS", LOCALE_PATHS)

INSTALLED_APPS = [
    "django.contrib.contenttypes",
    "django.contrib.auth",
    "django.contrib.sessions",
    "django.contrib.sites",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django_otp",
    "django_otp.plugins.otp_static",
    "django_otp.plugins.otp_totp",
    "two_factor",
    "grappelli",
    "grappelli_filters",
    "django.contrib.admin",
    "rangefilter",
    "admin_numeric_filter",
    "admin_auto_filters",
    "api",
]

Solution

  • I have solved the problem by updating my grappelli version from 2.15 to 3.0. I suspect this issue is similar to the problem I encountered, and upgrading versions seems to have solved it.

    The most visible part of the problem was the fact that a minified actions.min.js kept popping up in my static files, which seemed to not be the grappelli version of the actions.js file but the "vanilla" Django one, explaining the lack of the "Select all" functionality. I suspect a combination of my Django version and Grappelli caused this issue to be as annoying as it was. Version updates to both seem to be the most reliable solution.