3

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
  • 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... Commented Jan 8, 2021 at 2:31

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

3 Comments

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
Yes I agree, personally I prefer to put everything together ;)
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.
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

1 Comment

I appreciate it!
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
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.