2

I currently have the following in settings.py:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

#add app-specific static directory
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'project/static'),
    os.path.join(BASE_DIR, 'project/apps/blog/static/'),
    os.path.join(BASE_DIR, 'project/apps/users/static/'),
    os.path.join(BASE_DIR, 'project/apps/comments/static/'),
    os.path.join(BASE_DIR, 'project/apps/categories/static/'),
)

Should I be doing this in one line? Thanks very much.

  • 1
    you could have just one static root? like not in every app but like one folder. when you deploy your application you will have to run `collect static` anyway which will take care of your files in production... – hansTheFranz Jan 08 '21 at 02:31

3 Answers3

2

A better practice is to put all your static files in the same folder in your root directory instead of each app:

# ...
├── app1
├── app2
├── project
├── manage.py
├── media
├── requirements.txt
├── static
│   ├── css
│   ├── icons
│   ├── img
│   ├── js
│   └── vendor

Then in your settings.py assign this variable:

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]

staticfiles_dirs sets the directory and tells Django where to look up for your static files, in this example, our folder is named 'static' in our root directory, os.path.join will join the base directory(root) with static.

BTW STATIC_ROOT is usually used in a production environment, when you run 'collectstatic` command, all static files including your 3rd party apps will be copied to this 'staticfiles' folder.

Also, you can put templates of each app into the same folder in a similar way:

# root 
└── templates
    ├── app1
    ├── app2
    ├── app3
    ├── base.html
    └── index.html

And in your settings.py, add the directory of 'templates' folder.


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': { # ...
            ],
        },
    },
]

Personally, I think this would be much cleaner.

You can reference my project for the file structure: here

convers39
  • 312
  • 5
  • 12
  • 2
    There is no best practice about asset management, some people want it more granular and some don't, it is same thing with templates. This is why AppDirectoriesFinder exists – iklinac Jan 08 '21 at 02:50
  • 1
    Yes I agree, personally I prefer to put everything together ;) – convers39 Jan 08 '21 at 02:51
  • I kind of agree with both of you but there is a choice to make based on the number of apps you have in one project. If you have a large amount of apps with a static folder in each one of them, you will end up with many duplicates js and css files, and it will be very hard to manage them. These could be shared among all apps instead. In one of my project which contains many apps, I have only one js folder and one bootstrap folder for all apps. For images and other items that belong to specific apps only I put a subdirectory with the name of the app under the main static directory. – Robin May 12 '22 at 02:52
1

You can add custom static file finder that would sort you out, but generally if you have /static folder inside of the app it should be discovered by

django.contrib.staticfiles.finders.AppDirectoriesFinder

as documented

The default will find files stored in the STATICFILES_DIRS setting (using django.contrib.staticfiles.finders.FileSystemFinder) and in a static subdirectory of each app (using django.contrib.staticfiles.finders.AppDirectoriesFinder). If multiple files with the same name are present, the first file that is found will be used

Source

iklinac
  • 14,944
  • 4
  • 28
  • 30
0

I recommend to serve static files from Django project root directory as shown below. *My answer explains how to load CSS and JavaScript files in Django in detail:

django-project
 |-core
 |  └-settings.py
 |-my_app1
 |-my_app2
 |-static # Here
 |  └-my_app1
 |     |-css
 |     |  └-hello.css
 |     └-js
 |        └-hello.js
 |
 └-templates
    └-index.html

Then, set BASE_DIR / 'static/' to STATICFILES_DIRS in settings.py as shown below:

# "settings.py"

STATIC_URL = 'static/'
STATIC_ROOT = 'staticfiles/'
STATICFILES_DIRS = [
    BASE_DIR / 'static/' # Here
]
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129