[Django] #35822: App name hard-coded in collectstatic command forces name of overriding app name to be 'staticfiles'

10 views
Skip to first unread message

Django

unread,
Oct 8, 2024, 10:09:11 PM10/8/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Type: Bug
Status: new | Component:
| contrib.staticfiles
Version: 5.1 | Severity: Normal
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
In `django.contrib.staticfiles.management.commands.collectstatic`,
`Command.set_options()`, there is:
```python
ignore_patterns += apps.get_app_config("staticfiles").ignore_patterns
```
This looks for config `class StaticFilesConfig` in the app trying to
overwrite `ignore_patterns`. Because Django forces the class name to match
config name (in this case `StaticFiles`, the name of the app is forced to
be `staticfiles`, it cannot be anything else. Either the hard-coding in
collectstatic command set_options() should be changed, or document at
https://docs.djangoproject.com/en/5.1/ref/contrib/staticfiles
/#customizing-the-ignored-pattern-list should be changed for the example
which shows the Config can be named `MyStaticFilesConfig`, which is
clearly cannot be.

I have just started on Django (3-4 months) and I have looked at number of
places, this info is missing, hence raising this ticket.
--
Ticket URL: <https://code.djangoproject.com/ticket/35822>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 9, 2024, 1:33:12 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: new
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution:
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Sarah Boyce:

Old description:

> In `django.contrib.staticfiles.management.commands.collectstatic`,
> `Command.set_options()`, there is:
> ```python
> ignore_patterns += apps.get_app_config("staticfiles").ignore_patterns
> ```
> This looks for config `class StaticFilesConfig` in the app trying to
> overwrite `ignore_patterns`. Because Django forces the class name to
> match config name (in this case `StaticFiles`, the name of the app is
> forced to be `staticfiles`, it cannot be anything else. Either the hard-
> coding in collectstatic command set_options() should be changed, or
> document at https://docs.djangoproject.com/en/5.1/ref/contrib/staticfiles
> /#customizing-the-ignored-pattern-list should be changed for the example
> which shows the Config can be named `MyStaticFilesConfig`, which is
> clearly cannot be.
>
> I have just started on Django (3-4 months) and I have looked at number of
> places, this info is missing, hence raising this ticket.

New description:

In `django.contrib.staticfiles.management.commands.collectstatic`,
`Command.set_options()`, there is:
{{{#!python
ignore_patterns += apps.get_app_config("staticfiles").ignore_patterns
}}}
This looks for config `class StaticFilesConfig` in the app trying to
overwrite `ignore_patterns`. Because Django forces the class name to match
config name (in this case `StaticFiles`, the name of the app is forced to
be `staticfiles`, it cannot be anything else. Either the hard-coding in
collectstatic command set_options() should be changed, or document at
https://docs.djangoproject.com/en/5.1/ref/contrib/staticfiles
/#customizing-the-ignored-pattern-list should be changed for the example
which shows the Config can be named `MyStaticFilesConfig`, which is
clearly cannot be.

I have just started on Django (3-4 months) and I have looked at number of
places, this info is missing, hence raising this ticket.

--
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:1>

Django

unread,
Oct 9, 2024, 1:56:21 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: closed
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution:
| worksforme
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* resolution: => worksforme
* status: new => closed

Comment:

I followed the documented example and it works as expected

These were my steps:
- create a new Django project
- set `STATIC_ROOT = "static"`
- create a new app `python manage.py startapp app1`
Then followed the instructions
- copy paste the overriden AppConfig with something in `ignore_patterns`
- replace `'django.contrib.staticfiles'` with that class path
(`'app1.apps.MyStaticFilesConfig'`) in `INSTALLED_APPS` setting

Command uses new custom setting

Also in the shell
{{{
>>> from django.apps import apps
>>> apps.get_app_config("staticfiles").ignore_patterns
['test']
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:2>

Django

unread,
Oct 9, 2024, 5:23:54 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: closed
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution:
| worksforme
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by fishfin):

These are my steps on Windows 11, Python 3.12.7, Django 5.1.2, I use
pipenv: I know some of these steps don't matter, but I am unable to
recreate what you said, so listing everything.
{{{
$ mkdir myvenv & cd myvenv & mkdir .venv & pipenv --python 3.12 & pipenv
shell
$ pipenv install django
$ django-admin.exe startproject myproj & cd myproj
$ django-admin.exe startapp myapp
}}}

Edit myvenv/myproj/myproj/settings.py to:
1) Add `STATIC_ROOT = "static"` to the file
2) Replace item `'django.contrib.staticfiles'` in INSTALLED_APPS with
`'myapp.apps.MyappConfig'` (pointing directly to the Config class instead
of just app name).

Edit myvenv/myproj/myapp/apps.py to:
1) Replace
{{{
from django.apps import AppConfig
class MyappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
}}}
with
{{{
from django.contrib.staticfiles.apps import StaticFilesConfig
class MyappConfig(StaticFilesConfig):
name = 'myapp'
ignore_patterns = ["testpattern"]
}}}

Open shell:
{{{
$ cd myvenv/myproj
$ py manage.py shell
>>> from django.apps import apps
>>> apps.get_app_config('staticfiles').ignore_patterns
LookupError: No installed app with label 'staticfiles'.
>>> apps.get_app_config('myapp').ignore_patterns
['testpattern']
}}}

When you removed `'django.contrib.staticfiles'` from settings.py, I am not
sure how it is still able to find an app with that name. I am getting an
error as I had expected as seen above. Changing MyappConfig.name to
'staticfiles' doesn't help either. Changing parent class of MyappConfig
from StaticFilesConfig to AppConfig does not seem to be right.

Now, since we removed `'django.contrib.staticfiles'`, django doesn't know
about its management/commands directory, so `py manage.py collectstatic`
won't work.
{{{
$ py manage.py collectstatic
Unknown command: 'collectstatic'
Type 'manage.py help' for usage.
}}}

To make it work, I did the following:
{{{
$ mkdir myvenv/myproj/myapp/management/commands
}}}
Create following empty files:
{{{
myvenv/myproj/myapp/management/__init__.py
myvenv/myproj/myapp/management/commands/__init__.py
myvenv/myproj/myapp/management/commands/collectstatic.py
myvenv/myproj/myapp/management/commands/findstatic.py
}}}

Edit `myvenv/myproj/myapp/management/commands/collectstatic.py` and add
following code:
{{{
from django.contrib.staticfiles.management.commands.collectstatic import
Command
}}}
Edit `myvenv/myproj/myapp/management/commands/findstatic.py` and add
following code:
{{{
from django.contrib.staticfiles.management.commands.findstatic import
Command
}}}

Now:
{{{
$ py manage.py collectstatic
File "...\myvenv\.venv\Lib\site-
packages\django\contrib\staticfiles\management\commands\collectstatic.py",
line 103, in set_options
ignore_patterns += apps.get_app_config("staticfiles").ignore_patterns
LookupError: No installed app with label 'staticfiles'.
}}}
...which is the same error I got in django shell. If I am doing something
wrong, please let me know.
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:3>

Django

unread,
Oct 9, 2024, 5:41:50 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: new
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution:
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by fishfin):

* resolution: worksforme =>
* status: closed => new

Comment:

Please see my previous comment. Listed all steps to recreate.

Additionally:
{{{
>>> from django.apps import apps
>>> apps.app_configs
{'admin': <AdminConfig: admin>, 'auth': <AuthConfig: auth>,
'contenttypes': <ContentTypesConfig: contenttypes>, 'sessions':
<SessionsConfig: sessions>, 'messages': <MessagesConfig: messages>,
'myapp': <MyappConfig: myapp>}
}}}
There's no `staticfiles` app.
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:4>

Django

unread,
Oct 9, 2024, 5:59:13 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: closed
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution: invalid
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* resolution: => invalid
* status: new => closed

Comment:

You added a name.
This
{{{
class MyappConfig(StaticFilesConfig):
name = 'myapp'
ignore_patterns = ["testpattern"]
}}}
should be:
{{{
class MyappConfig(StaticFilesConfig):
ignore_patterns = ["testpattern"]
}}}

It inherits the name for `StaticFilesConfig`

So it works as documented
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:5>

Django

unread,
Oct 9, 2024, 6:38:36 AM10/9/24
to django-...@googlegroups.com
#35822: App name hard-coded in collectstatic command forces name of overriding app
name to be 'staticfiles'
-------------------------------------+-------------------------------------
Reporter: fishfin | Owner: (none)
Type: Bug | Status: closed
Component: contrib.staticfiles | Version: 5.1
Severity: Normal | Resolution: invalid
Keywords: collectstatic | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by fishfin):

I removed the name.
{{{
from django.contrib.staticfiles.apps import StaticFilesConfig
class MyappConfig(StaticFilesConfig):
# StaticFilesConfig.name = "django.contrib.staticfiles"
ignore_patterns = ["testpattern"]
}}}

Works fine.

I missed a number of things here: INSTALLED_APPS can point to a specific
AppConfig class, which in turn may have a name, which is the app Django
loads. This also loads the management commands in
`django.contrib.staticfiles`, so no overrides of commands were required. I
removed `myapp` as there's no need create one just for staticfiles
commands now, just shifted the overriding class to a file in myproj, and
changed settings.INSTALLED_APPS likewise.

Thank you.
--
Ticket URL: <https://code.djangoproject.com/ticket/35822#comment:6>
Reply all
Reply to author
Forward
0 new messages