* Removed type coercion. Options created by argparse are already coerced
to the correct type.
* Removed fallback default values. Options created by argparse already
have a default value.
* Used direct indexing. Options created by argparse are always set. This
eliminates the need to use dict.get().
New Storage.get_{accessed,created,modified}_time() methods convert the
naive time from now-deprecated {accessed,created_modified}_time()
methods into aware objects in UTC if USE_TZ=True.
When running collectstatic with a hashing static file storage backend,
URLs referencing other files were normalized with posixpath.normpath.
This could corrupt URLs: for example 'a.css#b/../c' became just 'c'.
Normalization seems to be an artifact of the historical implementation.
It contained a home-grown implementation of posixpath.join which relied
on counting occurrences of .. and /, so multiple / had to be collapsed.
The new implementation introduced in the previous commit doesn't suffer
from this issue. So it seems safe to remove the normalization.
There was a test for this normalization behavior but I don't think it's
a good test. Django shouldn't modify CSS that way. If a developer has
rendundant /s, it's mostly an aesthetic issue and it isn't Django's job
to fix it. Conversely, if the user wants a series of /s, perhaps in the
URL fragment, Django shouldn't destroy it.
Refs #26249.
collectstatic crashed when:
* a hashing static file storage backend was used
* a static file referenced another static file located directly in
STATIC_ROOT (not a subdirectory) with an absolute URL (which must
start with STATIC_URL, which cannot be empty)
It seems to me that the current code reimplements relative path joining
and doesn't handle edge cases correctly. I suspect it assumes that
STATIC_URL is of the form r'/[^/]+/'.
Throwing out that code in favor of the posixpath module makes the logic
easier to follow. Handling absolute paths correctly also becomes easier.
A @font-face declaration may contain a fragment that looks like a relative path,
e.g. @font-face { src: url('../fonts/font.svg#../path/like/fragment'); }
In this case, an incorrect path was passed to the storage backend, which raised
an error that caused collectstatic to crash.
This helps with testability of management commands.
Thanks to trac username daveoncode for the report and to
Tim Graham and Claude Paroz for the reviews.
When using ManifestStaticFilesStorage, deleted static files would be
correctly cleaned up by "collectstatic --clear", but the manifest file
would still contain the stale entries.
Thanks to tedtieken for the report
Considering that these apps only translate their app name, it's not
worth having a whole bunch of po files just for that. The translatable
app name for those apps will be integrated in Django core catalog.
Since d2e242d16c6dde6f4736086fb38057424bed3edb made isinstance()
calls work correctly on LazyObject, we can simplify the
implementation of is_local_storage added in
7e27885c6e.
Before 4befb30 the detection was broken because we used isinstance
against a LazyObject rather than against a Storage class. That commit
fixed it by looking directly at the object wrapped by LazyObject.
This could however be a problem to anyone who subclasses the
collectstatic management Command and directly supplies a Storage class.
Refs #21581.