Как настроить "Django" на создание нескольких директорий развертывания 'STATIC_ROOT' в файле settings.py?

Вот в чем проблема, при миграции нескольких 'STATICFILES_DIRS', у меня все работает, и сервер продолжает работать без ошибок...

... Вот сниппет к моему 'STATICFILES_DIRS' ...

...
STATIC_URL = 'Application/'

#Multiple Static Directories
STATICFILES_DIRS = [
    os.path.join('Application', 'Bootstrap'),
    os.path.join('Application', 'html'),
]
#End of Multiple Static Directories
STATIC_ROOT = 'Application/templates/Application'
...

... Что касается фактической проблемы, с которой я столкнулся во время выполнения команды "python3 manage.py runserver", то фрагмент error выглядит следующим образом...

...
STATIC_URL = 'Application/'

#Multiple Static Directories
STATICFILES_DIRS = [
    os.path.join('Application', 'Bootstrap'),
    os.path.join('Application', 'html'),
]
#End of Multiple Static Directories

#Multiple Static Root Directories
STATIC_ROOT = [
    os.path.join('Application', 'templates/Application'),
    os.path.join('Domains', 'https://example.com'),
]
#End of Multiple Static Root Directories
...

... Есть ли способы решить эту ошибку для того, чтобы Django читал/генерировал несколько 'STATIC_ROOT' директорий развертывания?

Привет, ~ Рикки Кеннибрю

TL;DR

To answer your question directly: no, there is no official way to use multiple STATIC_ROOTs in Django.

There may be some very hacky solutions (not recommended), but in general this is not how Django handles static files.

You didn't provide a traceback for the error you referring to, but I suspect it's something like:

TypeError: expected str, bytes or os.PathLike object, not list

Django expects STATIC_ROOT to be a single path, not a list of paths (as in your example). The STATIC_ROOT directory is not even used during development (when you run the runserver command), but Django validates the settings file and detects that the STATIC_ROOT setting is not configured properly.

More detailed explanation bellow.

Basic concepts

There are three main concepts (and also settings) related to static files (well, there are more, but these are the important ones for this question). I'll summarise them bellow, but please refer to the linked documentation for a full description.

STATIC_URL

STATIC_URL is a single URL at which your static files are served. This might be a URL path or a full URL (e.g. if you are using a subdomain for serving static files).

If your site is example.com and STATIC_URL is Application/ (as in your example), your static files are served at https://example.com/Application/.

The exact URL path for a given file depends on the file's location in relation to the STATIC_ROOT directory. So, if you have the main.css file directly in STATIC_ROOT, it will be available at https://example.com/Application/main.css. On the other hand, if the file is located in a subdirectory inside STATIC_ROOT, e.g css/main.css, then it will be available at https://example.com/Application/css/main.css.

The STATIC_URL setting is closely related to the static template tag. When referencing static files in templates, you shouldn't use hardcoded URLs directly. Instead, you should use the static template tag, e.g. {% static 'css/main.css' %}. Django then uses your STATIC_URL to generate the appropriate URL. If at any time you decide to change your STATIC_URL, e.g. from Application/ to static/, all these URLs will be updated automatically.

As you can see, you can't have multiple STATIC_URLs because Django wouldn’t know which one to use in templates (assuming you use the static template tag, as you should). And since the paths in these URLs represent real files located in the STATIC_ROOT directory, you cannot have multiple STATIC_ROOTs.

STATICFILES_DIRS

STATICFILES_DIRS are optional paths to search for static files. You can specify multiple values here.

By default, Django looks for static files in the static directory in each application you have in your INSTALLED_APPS setting. For example, if you created a Django app named myapp, Django will automatically find static files in the myapp/static directory.

Sometimes that's not enough. Let’s assume you have static files that are not associated with any specific app. In such cases, you may want to place these files in a global static directory, which may be located e.g. in the root directory of your project. You can use the STATICFILES_DIRS setting to tell Django about this in your settings.py file:

# This should already be in your settings (in modern Django versions)
BASE_DIR = Path(__file__).resolve().parent.parent

STATICFILES_DIRS = [
    BASE_DIR / "static",
]

Note that I provide a path relative to the BASE_DIR setting. This is generally the recommended way to build paths within a project. If you are using the default project template, then BASE_DIR should point to the project root (the directory where the manage.py file is located).

STATIC_ROOT

Finally, we come to the STATIC_ROOT setting. This is a single path to the directory where all static files are copied when you run the project in production.

STATIC_ROOT = BASE_DIR / "public/static"

Note that this should be an absolute path to a directory in your file system.

The important phrase here is „in production”. When you run the project locally using the runserver command, STATIC_ROOT is not used. Django will serve your static files directly from anywhere it can find. This includes the directories specified in STATICFILES_DIRS and all static directories inside your apps.

Another important thing is that you should not manually add any files to STATIC_ROOT. This is clearly stated in the documentation for the STATIC_ROOT setting:

This should be an initially empty destination directory for collecting your static files from their permanent locations into one directory for ease of deployment; it is not a place to store your static files permanently. You should do that in directories that will be found by staticfiles’s finders, which by default, are 'static/' app sub-directories and any directories you include in STATICFILES_DIRS).

Later, when you deploy your project to production, you can no longer use runserver and have to take care of serving static files yourself (e.g. using a production-ready server like Nginx). Then you generally want all static files to be in one place (STATIC_ROOT) so that they can be easily served. To do this, you use the collectstatic command, which copies all static files to STATIC_ROOT.

The whole idea of the STATIC_ROOT directory is that it collects all the static files from different places (e.g. multiple STATICFILES_DIRS), so there's really no point in having multiple STATIC_ROOTs.

Recap

So, to summarise:

  • You don’t have to specify STATICFILES_DIRS at all, if you place your static files in static directories inside your apps.
  • You can specify multiple STATICFILES_DIRS, if you want to use other location(s) for your static files.
  • You can only specify one STATIC_URL and one STATIC_ROOT.
  • STATIC_ROOT is used only in production to serve all your static files from a single location.
  • You don’t add static files manually to your STATIC_ROOT (you use the collectstatic command to copy all static files into STATIC_ROOT).

I don’t know what your exact use case is, but if you want some kind of separation, I recommend just using subdirectories in a single STATIC_ROOT:

  • <STATIC_ROOT>/some_dir1
  • <STATIC_ROOT>/some_dir2

If you create the some_dir1 directory inside any of the STATICFILES_DIRS, then it will be copied to STATIC_ROOT when you run collectstatic.

Вернуться на верх