4

Django 3.0.8

Python 3.7.x

I've got a Django project with a few apps. I'm trying to make some 'default' error pages for like 400, 403, 404, 500 errors. I've done that and the appropriate templates display - but without any styling or JS.

In the 404 error page, I'm trying to link to the CSS from one of the apps so the correct styling gets applied - but in the console, I see this error:

Refused to apply style from 'http://127.0.0.1:8000/static/launcher/dist/css/launcher.css' because of its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

The file exists there, however.

That particular CSS file lives in two places: in the app directory and it also lives in the STATIC_ROOT because I ran the python manage.py collectstatic command.

The STATIC_URL is set to /static/

The CSS file is located at:

  • project_dir/launcher/static/launcher/dist/css/launcher.css

  • project_dir/static/launcher/dist/css/launcher.css

My 404 template lives at:

project_dir/templates/404.html

My link to the CSS looks like this:

<link rel="stylesheet" type="text/css" href="{% static 'launcher/dist/css/launcher.css' %}" />

My project URL's look like this:

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("launcher.urls")),
    path("app2/", include("app2.urls")),
    path("app3/", include("app3.urls")),
    path(
        "robots.txt",
        TemplateView.as_view(
            template_name="robots.txt", content_type="text/plain"
        ),
    ),
    path(
        "favicon.ico",
        RedirectView.as_view(
            url=staticfiles_storage.url("favicon.ico"), permanent=False
        ),
        name="favicon",
    ),
]
urlpatterns += static(
    settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
)
urlpatterns += static(
    settings.STATIC_URL, document_root=settings.STATIC_ROOT
)

I've tried a lot of different solutions (like getting rid of comments in the CSS or changing the type in the HTML link) but nothing has worked thus far.

What is the best way to accomplish this?

EDIT TO ADD: My 404.html page looks like this:

{% extends 'error_base.html' %}
{% load static %}

{% block css_imports %}
    <link rel="stylesheet" type="text/css" href="{%  static 'launcher/dist/css/launcher.css' %}" />
{% endblock %}

{% block script_imports %}
    <script src="{% static 'launcher/dist/js/vendors~main.f11c6fb90f8f72673956.js' %}"></script>
    <script src="{% static 'launcher/dist/js/main.dce999efa12cf745c86d.js' %}"></script>
{% endblock %}

{% block content %}
    <h1>Whoops!</h1>
    404
    <h3>We are having some issue finding that particular item.</h3>
    <p>If you feel this was due to an error - please contact us!
    </p>
{% endblock %}

The JS files give 404 errors as well, but I figure once I find out the cause of the CSS issues, I can figure out the JS issues as well. The 'error_base.html' file is essentially a boilerplate HTML file with the appropriate blocks in the appropriate spots for the blocks listed in the 404.html page.

ADDITIONAL EDIT TO ADD :

My static files settings look like this:

# Static files (CSS, JavaScript, Images)
STATIC_URL = "/static/"

STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'launcher/static/'),
    os.path.join(BASE_DIR, 'app1/static/'),
    os.path.join(BASE_DIR, 'app2/static/'),
]

# Media files 
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

EDIT TO ADD: Tree structure looks like this:

├── README.md
├── project_dir
│   ├── __init__.py
│   ├── context_processors.py
│   ├── settings.py
│   ├── unit-test-settings.py
│   ├── urls.py
│   ├── utils.py
│   └── wsgi.py
├── geckodriver.log
├── app_1
   ├── static
   │   └── app_1
   │       ├── dist
   │       │   ├── css
   │       │   │   └── app_1.css
   │       │   └── js
   │       │       ├── main.f3eaca15a899d1a9d4e4.js
   │       │       └── vendors~main.48489b4c92919034fc8f.js
   │       ├── fa-grav.png
   │       ├── grav.png
   │       ├── grav_30.png
   │       └── src
   │           ├── css
   │           │   └── style.css
   │           ├── html
   │           │   └── webpack_bundles.html
   │           ├── js
   │           │   ├── index.js
   │           │   └── indellis_form.js
   │           └── scss
   │               └── app_1.scss
   └─ ....other standard app files
├── app_2
   ├── static
   │   └── app_2
   │       ├── dist
   │       │   ├── css
   │       │   │   └── app_2.css
   │       │   └── js
   │       │       ├── main.cedd2abecaa899d1a9d4e4.js
   │       │       └── vendors~main.48325ceds92919034fc8f.js
   │       ├── fa-grav.png
   │       ├── grav.png
   │       ├── grav_30.png
   │       └── src
   │           ├── css
   │           │   └── style.css
   │           ├── html
   │           │   └── webpack_bundles.html
   │           ├── js
   │           │   ├── index.js
   │           │   └── registration_form.js
   │           └── scss
   │               └── app_2.scss
   └─ ....other standard app files
├── launcher
│   ├── static
│   │   └── launcher
│   │       ├── dist
│   │       │   ├── css
│   │       │   │   └── launcher.css
│   │       │   └── js
│   │       │       ├── main.75ef788b0aea38c3c71b.js
│   │       │       └── vendors~main.d806da1f66faa822a6ef.js
│   │       └── src
│   │           ├── css
│   │           │   └── style.css
│   │           ├── html
│   │           │   └── webpack_bundles.html
│   │           ├── js
│   │           │   └── index.js
│   │           └── scss
│   │               └── launcher.scss
   └─ ....other standard app files
├── manage.py
├── pyproject.toml
├── pytest.ini
├── requirements.txt
├── setup.cfg
├── static
│   ├── app_1
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── app_1.css
│   │   │   └── js
│   │   │       ├── main.f3eaca15a899d1a9d4e4.js
│   │   │       └── vendors~main.48489b4c92919034fc8f.js
│   │   ├── fa-grav.png
│   │   ├── grav.png
│   │   ├── grav_30.png
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   ├── index.js
│   │       │   └── indellis_form.js
│   │       └── scss
│   │           └── app_1.scss
│   ├── project_dir
│   │   ├── favicon.ico
│   │   ├── icons
│   │   │   ├── android-chrome-144x144.png
│   │   │   ├── apple-touch-icon-120x120-precomposed.png
│   │   │   ├── apple-touch-icon-120x120.png
│   │   │   ├── apple-touch-icon-152x152-precomposed.png
│   │   │   ├── apple-touch-icon-152x152.png
│   │   │   ├── apple-touch-icon-180x180-precomposed.png
│   │   │   ├── apple-touch-icon-180x180.png
│   │   │   ├── apple-touch-icon-60x60-precomposed.png
│   │   │   ├── apple-touch-icon-60x60.png
│   │   │   ├── apple-touch-icon-76x76-precomposed.png
│   │   │   ├── apple-touch-icon-76x76.png
│   │   │   ├── apple-touch-icon-precomposed.png
│   │   │   ├── apple-touch-icon.png
│   │   │   ├── browserconfig.xml
│   │   │   ├── favicon-16x16.png
│   │   │   ├── favicon-32x32.png
│   │   │   ├── mstile-144x144.png
│   │   │   ├── mstile-150x150.png
│   │   │   ├── safari-pinned-tab.svg
│   │   │   └── site.webmanifest
│   │   └── proj_icon.ico
│   ├── launcher
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── launcher.css
│   │   │   └── js
│   │   │       ├── main.75ef788b0aea38c3c71b.js
│   │   │       └── vendors~main.d806da1f66faa822a6ef.js
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   └── index.js
│   │       └── scss
│   │           └── launcher.scss
│   ├── app_2
│   │   ├── dist
│   │   │   ├── css
│   │   │   │   └── app_2.css
│   │   │   └── js
│   │   │       ├── main.cedd2abecaa899d1a9d4e4.js
│   │   │       └── vendors~main.48325ceds92919034fc8f.js
│   │   ├── fa-pdf.png
│   │   ├── id_card_30.png
│   │   ├── rc-u.png
│   │   ├── rg.png
│   │   └── src
│   │       ├── css
│   │       │   └── style.css
│   │       ├── html
│   │       │   └── webpack_bundles.html
│   │       ├── js
│   │       │   └── index.js
│   │       └── scss
│   │           └── app_2.scss
├── templates
│   ├── 400.html
│   ├── 403.html
│   ├── 404.html
│   ├── 500.html
│   ├── base.html
│   ├── error_base.html
│   └── robots.txt
KarthikNayak98
  • 363
  • 3
  • 13
Hanny
  • 580
  • 3
  • 16
  • 44
  • 1
    So this is the reason for the error. Must be something with your static config. Now, do you see anything in server console? And are you able to access other static files? – Yuri Nudelman Jul 27 '20 at 14:27
  • @YuriNudelman I cannot get to any static files for some reason directly from the browser. I've updated my settings with my static information as well. – Hanny Jul 27 '20 at 14:34

3 Answers3

7

TLDR:

If you want to serve static files with DEBUG=False using a local development server, you need to use the --insecure flag:

python manage.py runserver --insecure

Why you get the error:

Every time you render html in your browser, behind the scenes a request is made to fetch each of your static files. So in your case, the 404.html template is telling your browser to fetch http://127.0.0.1:8000/static/launcher/dist/css/launcher.css. If your django server doesn't know where that file is, it will respond with the 404.html template instead of the css, which has a MIME type of text/html, and not text/css, hence your error.

Why django can't find the css files:

If you look at the source code for the static function that you call in your urls.py, it looks something like this:

from django.conf.urls.static import static

def static(...):
    if not settings.DEBUG:
        return []

    return [
        re_path(...)
    ]

Which means that the re_path that is used to render static files, is no longer there, since you set DEBUG=False to test your 404.html template...

Credit to Dmitry Shevchenko for the shortcut.

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • Is there a negative to using that 'static' method as opposed to the default django builtin? – Hanny Aug 03 '20 at 12:40
  • @Hanny See [Why does DEBUG=False setting make my django Static Files Access fail?](https://stackoverflow.com/q/5836674/8601760). – aaron Aug 03 '20 at 14:09
  • @Hanny You shouldn't use this method in production. Instead static files should be handled by your server (Nginx, Apache, etc.) – Lord Elrond Aug 03 '20 at 15:42
1

This usually means the page can't find your css file and is trying to load your not found page which is html.

Try using a full absolute path for the link on your error page and see if that works:

<link rel="stylesheet" type="text/css" href="/static/launcher/dist/css/launcher.css"/>

If that works, then I would next check to make sure the static variable Django is replacing is actually set correctly at runtime. I suspect the path is slightly off.

If that doesn't work, try the full absolute path to the css file in your app folder instead of STATIC_ROOT:

<link rel="stylesheet" type="text/css" href="/launcher/static/launcher/dist/css/launcher.css"/>

If that works and the first one didn't, then I would suspect a problem somewhere in the configuration/translation when your files get collected to STATIC_ROOT. I'm not familiar with the process so I'm not sure exactly what get's moved where and what metadata gets changed, if any. I'd imagine none does, but the only way to be sure is to try it out.

Update:

It looks like your STATICFILES_DIRS are not pointing to the end folders the css files are actually in. Complete those paths and it may work (add dist/static... etc.)

Salvatore
  • 10,815
  • 4
  • 31
  • 69
0

I would have write a comment but i can't, due to reputation, because i am new. You should try to access the link (http://127.0.0.1:8000/static/launcher/dist/css/launcher.css) in your browser! If the css file doesn't open the path is the problem.

Another possible cause is a comment at the beginning of the css file.

aph
  • 111
  • 1
  • 7