When specifying paths to assets like JavaScript files, but also CSS, the Django documentation states:
> Any links to the file in the codebase should point to the compressed > version. > <https://docs.djangoproject.com/en/3.0/internals/contributing/writing-code/javascript/#javascript-patches> This statement however does not properly reflect Django's internal handling of such assets, for instance in https://github.com/django/django/blob/master/django/contrib/admin/helpers.py#L83-L84 https://github.com/django/django/blob/master/django/contrib/admin/options.py#L639-L648 https://github.com/django/django/blob/master/django/contrib/admin/options.py#L2026-L2028 https://github.com/django/django/blob/master/django/contrib/admin/widgets.py#L446-L460 we see, that Django only serves the minimized version of the file, when not in DEBUG mode. This inconsistent handling of assets can cause other problems for third party apps, if they follow the documentation as show in the first link. If in their Media definition they refer to the minimized version of a Django asset, say 'admin/js/vendor/jquery/jquery.min.js', then the automatic sorting does not work anymore in DEBUG mode. If on the other side they refer to 'admin/js/vendor/jquery/jquery.js', then automatic sorting fails in production. There are two solutions to this problem. *Either* The documentation explicitly states that when a Media definition refers to internal Django assets, one *must* distinguish between the minimized and unminimized version, just as Django's internal Media definitions do (see code examples above). This however can easily be forgotten and errors therefore become visible only after deployment. *Or* We rewrite the FileSystemFinder and AppDirectoriesFinder so that in DEBUG mode, Django looks if an unminimized version of the same asset exists, and if so it then serves that. Doing that automatically is easy, because the general convention is, that the .min infix is always placed immediately before the .js- or .css file extension. In many of my projects I therefore use these two alternative finders, which do exactly that: import os from django.conf import settings from django.contrib.staticfiles.finders import (FileSystemFinder as FileSystemFinderBase, AppDirectoriesFinder as AppDirectoriesFinderBase) class FileSystemFinder(FileSystemFinderBase): """ In debug mode, serve /static/any/asset.min.ext as /static/any/asset.ext """ locations = [] serve_unminimized = getattr(settings, 'DEBUG', False) def find_location(self, root, path, prefix=None): if self.serve_unminimized: # search for the unminimized version, and if it exists, return it base, ext = os.path.splitext(path) base, minext = os.path.splitext(base) if minext == '.min': unminimized_path = super().find_location(root, base + ext, prefix) if unminimized_path: return unminimized_path # otherwise proceed with the given one path = super().find_location(root, path, prefix) return path class AppDirectoriesFinder(AppDirectoriesFinderBase): serve_unminimized = getattr(settings, 'DEBUG', False) def find_in_app(self, app, path): matched_path = super().find_in_app(app, path) if matched_path and self.serve_unminimized: base, ext = os.path.splitext(matched_path) base, minext = os.path.splitext(base) if minext == '.min': storage = self.storages.get(app, None) path = base + ext if storage.exists(path): path = storage.path(path) if path: return path return matched_path In my opinion this approach makes Django's internal and 3rd party package code more readable, because it removes the clutter of case distinction between DEBUG and production mode for each referred JavaScript and CSS asset. It also might be less error prone. -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/dd904eeb-a877-48d3-81fa-e72fe71a6735%40googlegroups.com.