Why can't I serve my static files to Django? - django

Before anyone marks this as a duplicate I have seen all of the other questions on similar topics and tried all of the solutions without effect.
My Django application is small and I am happy to serve the static files from the same server
In settings.py I have
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
I have uploaded my application to the server and run
python.manage.py collectstatic
All of my static files are in the appropriate directories under staticfiles
project-root
├── staticfiles
│   ├── css
│   │   ├── base.css
│   ├── js
│   │   ├── common.js
In my html I have
{% load static %}
<link href="{% static 'css/base.css' %}" rel="stylesheet">
On loading the page I get the error
Refused to apply style from '<URL>' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
I think this is because it cannot find the css file
Where am I going wrong? Do I need to provide any more information?

project_name - app_name - static - app_name - css/js file
<link rel="stylesheet" href="{% static 'app_name/style.css' %}">

My problem has been solved by installing the whitenoise package. (I have not seen this recommended on the responses to similar questions around this problem)
pip install whitenoise
And add it to the middleware section of settings.py
MIDDLEWARE = [
...
'whitenoise.middleware.WhiteNoiseMiddleware',
...
]
All of my static files are now loaded and the site works perfectly with no further configuration
(I am assuming that the problem might have been caused by a quirk in the site's host's server settings.)

Related

Django : cannot find the static files

In my Django project, the settings are the following ones:
A settings folder, including a base.py and a production.py files.
The base folder defines a path taking into account this tree:
BASE_DIR = os.path.dirname(
os.path.dirname(os.path.abspath(
os.path.join(__file__, os.pardir))))
And the static is defined as such:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
When I launch collectstatic the static folder is mounted at the root of the project, as planned.
However, the static files are not found neither by the html pages, although configured as seach:
{% load static %}
<!DOCTYPE html>
<html lang="eng">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'style_sheet.css' %}">
<title>{% block title %}Advocacy Project{% endblock %}</title>
</head>
and when I check with findstatic, it looks like it does not look into the right folders:
python manage.py findstatic style_sheet.css --settings my_project.settings.production --verbosity 2
No matching file found for 'style_sheet.css'.
Looking in the following locations:
/Users/my_name/Documents/my_project/venv/lib/python3.7/site-packages/django/contrib/admin/static
My question is: How could I make Django check in the right folders ?
Thanks ASFAW AYALKIBET support here is a detailed process to install Whitenoise on Django with multiple settings.
Install Whitenoise pip install Whitenoise
Create settings folder in the project folder.
Add base.py and production.py along with the __init__.py file in this folder.
in production.py add
DEBUG = False
In the settings, amend BASE_DIR as such :
BASE_DIR = Path(__file__).resolve().parent.parent.parent
insert 'whitenoise.runserver_nostatic'in INSTALLED_APPS and 'whitenoise.middleware.WhiteNoiseMiddleware' in MIDDLEWARE,(cf whitenoise official doc).
Again in the settings, add STATIC_ROOT = BASE_DIR / 'staticfiles'
In wsgi.py amend the settings path:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_project.settings.production')
then you can collect the static files using:
python manage.py collectstatic --settings settings.my_project.production
Launch the servers:
gunicorn my_project.wsgi to check the production mode
python manage.py runserver --settings settings.my_project.base to use the debug mode.
First check if debug = False or True in your setting. Django will not host your static files in Debug = False mode. You have to use something like whitenoise to host you static files in production.

Django app on Azure not getting static files

Got my Django project on a Azure webapp, but when I call on SSH terminal:
Python manage.py collectstatic
It says 252 files copied but my static files are not visible on my templates and static folder in wwwroot its empty...Here's my wwwroot structure:
wwwroot
|---Myproject
|---manage.py
|---oryx-manifest.toml
|---hostingstart.html
|---static //With all my static files
├── myapp
│ ├── migrations
│ ├── __pycache__
│ ├── static
| | |---Images
| | | |--myimage.png
| | | |--myimage2.png
│ └── templates
And this is my settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Any idea why or what am I doing wrong ?, does Azure collect different ?
EDIT> When I go to my website my images don´t show...Im calling them like this on template:
{% load static %}
<img src="{% static 'Images/myimage.png' %}" /><br>
EDIT 2 /////
In wwwroot creates indeed a folder with all my statics, but when I load my template they don´t show, in wen console I get this error for myimage.png and myimage2.png :
Failed to load resource: the server responded with a status of 404 (Not Found)
Found it !!
Just had to add this: + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to url patterns like this:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('myapp/', include('myapp.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
And it did the trick, hope it helps to anyone else!!
Django does not serve static files in production mode.
The only time it serves static files is when you turn DEBUG = True which is in development mode and this is not recommended in a production setting.
Django recommends to serve static files via CND or any other webserver. However if your website is minimal and does not get high volume traffic you can serve your static files using Django whitenoise and here is how you do it.
The below solution works on python 3.7 and Django 3.2
Step 1: Install whitenoise package
pip install whitenoise
Step 2: Ensure your BASE_DIR looks like the below
BASE_DIR = Path(__file__).resolve().parent.parent
Step 3: Add these to your settings.py. If you get any errors try commenting out STATICFILES_STORAGE and check
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Step 4: WhiteNoise middleware should be placed directly after the Django SecurityMiddleware (if you are using it) and before all other middleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]
Step 5: Ensure this is how you reference static files in your templates(also check if you have {% load static %} mentioned in your template
<link rel="stylesheet" type="text/css" href="{% static 'appname/styles.css' %}">
Step 6: Run collect static
python manage.py collectstatic
Step 7: Turn DEBUG = False and run the server to verify it works.
Some additional resources to read further:
whitenoise
Django on Azure - beyond "hello world"
Few points to note:
Below line will change
STATIC_ROOT = (os.path.join(BASE_DIR, 'Myproject/static_files/'))
to
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
You are using pointing to completely different folder here. Hence always empty You need the collectstatic command to copy files to
Project > static directory
Below remove the line os.path.join(BASE_DIR, 'static/')...
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'), #Not Required since you already mentioned it in STATIC_URL
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
Reason:
STATIC_ROOT is the folder where static files will be stored after
using manage.py collectstatic
The absolute path to the directory where collectstatic will collect
static files for deployment.
If the staticfiles contrib app is enabled (default) the collectstatic management command will collect static files into this
directory. See the howto on managing static files for more details
about usage.
STATICFILES_DIRS is the list of folders where Django will search for
additional static files aside from the static folder of each app
installed.
This setting defines the additional locations the staticfiles app will
traverse if the FileSystemFinder finder is enabled, e.g. if you use
the collectstatic or findstatic management command or use the static
file serving view.
If issue still persists check your static file directory in apache mod_wsgi config file in the server if it is configured properly.
Check this link for help on that >> https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/modwsgi/
Cheers!!!
I would recommend checking out Whitenoise for serving your static files with Django. I haven't had an issue serving them since integrating Whitenoise. Try swapping it out with your current static file finders setup.
http://whitenoise.evans.io/en/stable/django.html

Django not serving static files while STATIC_ROOT configured

I have a cloned project and I need to serve the static files with Django itself. It is my first time serving static files this way (in the past I used Nginx/Apache to serving media and static files). here is my try to serve static files by Django itself in production:
1- Adding STATIC_URL and STATIC_ROOT to settings.py:
...
STATIC_URL = '/static/'
STATIC_ROOT = os.environ.get('DH_STATIC_ROOT_DIR', os.path.join(BASE_DIR, 'static/'))
2- project's directory tree:
├── my_project
│   ├── DH
│   ├── env
│   ├── apps
│   ├── manage.py
│   ├── README.md
│   ├── requirements.txt
│   ├── static
│   └── templates
3- running ./manage.py collectstatic and working well. here is static/ directory's tree after this command (from past some static file exists in static directory because this project is MVT and loading templates):
├── admin
├── css
├── fonts
├── js
├── media
└── plugins
4- let Django serve static in production( in urls.py):
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', index, name='index'),
path('admin/', admin.site.urls)
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
5- how html templates reference to static files:
{% load static %}
...
<link href="{% static 'plugins/global/plugins.bundle.css' %}" rel="stylesheet" type="text/css" />
For example, in Chrome (inspect) I can see the template page request to http://127.0.0.1:8000/static/media/logos/logo-6.png that static/media/logos/logo-6.png exist (all request to static files raise 404 HTTP status code). with this configuration not working even in DEBUG=True what I am doing wrong? Thank you in advance.
As documentation states, serve not suppose to be used in production. If you don't want to use nginx or apache, then consider using whitenoise. All you need to do is install it by pip install whitenoise and add these lines to middleware:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]

Setup of static files in Heroku not working locally for Django

I am setting up a web app with Django 2.2 in Heroku and I was able to deploy it successfully in production but the app doesn't load the css files locally every time I try to run heroku local web.
This is how I setup the configuration of my files in my Django app.
- src
- live-static
- media-root
- static-root
- main_app
- urls.py
- wsgi.py
- __init__.py
- settings
- __init__.py
- base.py
- local.py
- production.py
- pages
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
- templates
- main_app
- home.html
- templates
- base.html
- static
- main_app
- css
-cover.css
- img
-myimage.jpg
- admin
- css
- img
- js
The following code is a snippet of the configurations from the production and local files:
production.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
STATIC_ROOT = os.path.join(BASE_DIR, 'live-static', 'static-root')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
local.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
STATIC_ROOT = os.path.join(BASE_DIR, 'live-static', 'static-root')
My css and jpg files are not rendered locally but they are rendered in production.
base.html
{% load static %}
<link href="{% static 'main_app/css/cover.css' %}" rel="stylesheet">
<img src="{% static 'main_app/img/myimage.jpg' %}" >
I expect that when I run heroku local web I should be able to see the css and images rendered.
I am not completely sure about the answer to this question. But why don't you try typing in heroku local:run python manage.py collectstatic and see if it renders your page.
Sorry about posting this as an answer and not as a comment(don't have a high rep).
I found out that the local.py file was missing the middleware whitenoise.middleware.WhiteNoiseMiddleware which is mandatory for visualizing the static files in Django.

Django static files in production not loaded

I have a problem with static files in my Django application.
I create a simple blog app with Django REST Framework and Angular 6. It's working fine in my local development environment, but I have a problem with deploying it to production. The thing is, the app is loading (I know that because the root route is a redirection to /app and I am being redirected correctly) but there are no static files loaded.
Here is part of my configuration related to the static files:
STATIC_URL = '/static/'
BASE_DIR = os.path.join(
os.path.dirname(os.path.dirname(__file__)), '..', '..', '..'
)
STATIC_ROOT = os.path.join(BASE_DIR, 'app', 'static')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend'),
]
INSTALLED_APPS = [
...
'django.contrib.staticfiles'
...
]
The paths are correct, I triple-checked them to be sure. And here are routes configured in Django application:
urlpatterns = [
url('^api/', include(api_patterns)),
url('^admin/', admin.site.urls),
url('^app/', serve, kwargs={'path': 'index.html'}),
url('^$', HomepageView.as_view(), name='homepage-redirection'),
]
I am able to run manage.py collectstatic without any errors and all static files are correctly copied to the static directory. Static files for admin application are not loaded correctly as well. Here is a rough structure of directories in my project:
├── app
│   └── (python code here)
├── frontend
│   └── (angular code here)
├── media
│   └── (empty for now)
└── static
  └── (static files for Django)
The application server is nginx with Phusion Passenger (this was configured by my the company I rent the server from). I don't really know what else I can add here. Does anyone have any idea what can be wrong here? Maybe some hint would be the fact that the API endpoints are not accessible. I have access to admin application, but not to API (both configured in the same urls file).