nomad
nomad

Reputation: 983

Django website giving trouble serving static files

I am working on a multi-app website. And I have bunch of noob questions. My dir structure looks like as below:

/var/www/html/portal
    src/
        manage.py
        portal/
        static/
            admin/
            css/
            img/
            js/
            fonts/
        templates/
            base.html
            homepage.html
    venv/
  1. Is my dir structure as per as Django standards?
  2. Are my STATIC files settings correct?

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

Or should it be

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
  1. Should I collectstatic after copying all my static files such as css,js etc or I can do it before copying files in those dirs?
  2. If I do collectstatic without mentioning STATIC_ROOT I get an exception django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.

But when I replace STATICFILES_DIRS with the following, my .css files stop serving. What am I doing wrong?

STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')

Upvotes: 2

Views: 3379

Answers (4)

QT-1
QT-1

Reputation: 996

This seems to work in current django (2.2) :

from django.conf.urls.static import serve

urlpatterns += [
    path(settings.STATIC_URL[1:], serve, {'document_root': settings.STATIC_ROOT })
]

Upvotes: 0

pawel.ad
pawel.ad

Reputation: 691

You don't need to run staticfiles when you're running a development server and DEBUG is set to True.

Static and media files can be then served directly via the web process (Docs) with adding these lines to your main urls.py:

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

As to the whole STATIC_URL, STATIC_ROOT, MEDIA_URL and MEDIA_ROOT, they're all related to how you'll serve your app in production, with a proper webserver.

What usually happens then is that the webserver (i.e. Nginx) handles serving files, not the Django app. But the Django app needs to know where are they. So:

STATIC_URL and MEDIA_URL need to be the same in your Django app settings and in your webserver config, for example with Nginx:

STATIC_URL = '/static/'
MEDIA_URL = '/media/'
...

location /static {
    alias /home/myusername/myproject/static/;
}
location /media {
    alias /home/myusername/myproject/media/;
}

STATIC_ROOT MEDIA_ROOT are 100% about how you want to structure your project on the server. Assuming the above, you need to work out how to point it to /home/myusername/myproject/static/.

Example of my settings:

BASE_DIR = Path(__file__).parent.parent.parent

MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))

STATIC_URL = '/static/'
STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles'))

Media files will be directly uploaded to the MEDIA_ROOT, but notice that you need to somehow get the static files from your applications (which could be in a number of folders, a library you use can have some extra static files, Django Admin has then, etc.) to the folder that Nginx is pointed to (which should be the same as STATIC_ROOT). That's where collectstaticfiles comes in and copies all your static files to that directory.

Upvotes: 4

tthayer
tthayer

Reputation: 513

Remember that if you have DEBUG set to 'False' it will ignore the staticfiles setting because it is expected that your webserver will be serving this directly. This caught me out a few times until I realized I hadn't updated the staticfiles folder (which I keep in a separate repository for reasons I can't remember now).

Upvotes: 2

Corey Gumbs
Corey Gumbs

Reputation: 382

In regards to directory structure, there are differences of opinion on how it should be set up. A quick google search can bring up some websites and discussions on Django project structures. I recommend reading some of the information to determine what is best for your and your project.

The Django documentation has a best practices page as well that is a good resource/reminder. Django Best Practices.

I mainly followed the Two Scoops of Django directory structure. The Two Scoops has helped me a lot in understanding this. My own twist looks something like this.

src/
  app/
    templates/
       app_name/
         base.html
         other_pages.html
    tests/
       tests.py
    app_files.py
  static/
    images/
    css/
    etc..
  templates/
    global_includes/
        include_file.html
    base.html

The collectstatic should not effect the serving of your static files during development. From what I have learned, collectstatic is more for when you are serving your static files during deployment from a separate server, or aws, heroku, etc. More info can be found here in the docs: Managing Static Files, staticfiles app, Deploying static files

I have learned that if my CSS files are not serving, it usually has something to do with my path. Chrome developer tools inspect element/console helps me with any path errors.

Have you added

+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

to your your main urlpattern/urls.py?

Here is more information on serving files during development: Serving static files during development.

Lastly check that your BASE_DIR is following the correct path for your project. You may have to change it.

I hope this helps.

Upvotes: 2

Related Questions