Heroku static files not loading, Django - python

I'm trying to push my Django project to Heroku, but it isn't loading the staticfiles.
I used this to setup the things, everything is fine but I'm not able to fix the issue with static files.
My directory structure is like this
help_the_needy
help_the_needy
__init__.py
settings.py
urls.py
views.py
wsgi.py
manage.py
Procfile
requirements.txt
static
css
font-awesome
fonts
img
js
templates
base.html
display_list2.html
index.html
Here is the complete code (all files).
This is my settings.py.
I tried alot of things to fix this, but nothing seems to work.
When I push it does copy static files but it's not loading them.
Can someone please point me to my mistake? Where is it wrong?

I have been dealing with the same problem too. And here are the 2 things that I changed in my code.
(I'm using Django 1.7)
1) settings.py
I add these lines to the setting files
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
# Add to this list all the locations containing your static files
)
STATIC_ROOT: this tells Django where to (a) put the static files when you run python manage.py collectstatic and (b) find the static files when you run the application
TEMPLATE_DIRS: this tells Django where to look for your static files when it search for statics files when you run python manage.py collectstatic
2) wsgi.py
Originally my file was:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxxx.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
And I changed it to:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxxx.settings")
from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise
application = get_wsgi_application()
application = DjangoWhiteNoise(application)
Read here for more information on whitenoise: https://devcenter.heroku.com/articles/django-assets#whitenoise
Also, remember to install whitenoise:
pip install whitenoise==2.0.6
Before deploying the project, run:
python manage.py collectstatic
This will create a folder indicated by STATIC_ROOT (declared in your settings.py), containing all your static files.

Since it's been a few years since this was posted (and it still pops up when I search for the issue), here's what worked for me in Django 3.2.
pip install whitenoise
Make sure in settings.py you have
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Add whitenoise to your Middleware:
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
]
Make sure the directory you specified as the STATIC_ROOT (staticfiles) exists in your base directory and is not empty.
After that, I committed the changes and Heroku was able to build the static files and everything worked fine.

pip install whitenoise
Add whitenoise to requirement.txt.
and also add whitenoise in the middleware of settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', #add whitenoise
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Follow the steps in https://devcenter.heroku.com/articles/django-assets

Your STATICFILES_DIRS setting is wrong. It should be pointing to the actual location of the "static" directory containing the files:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)

It looks like django don't know where your static_root is.
This folder is autogenerated when you fire manage.py collectstatic
Make sure that the folders static and templates are inside your django app. You didn't created a django app to put this folders into. You created a django project the next step is to create a django app with something like this python manage.py startapp polls
# Absolute filesystem path to the Django project directory:
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
# Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(DJANGO_ROOT)
STATIC_URL = '/static/'
STATIC_ROOT = normpath(join(SITE_ROOT, 'static_root'))

Your urls.py file lacks the setting to manage and route requests for static resources.
in order to provide access to static resorces you must add to urlpatterns of urls.py:
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
)

Related

My website was showing CSS fine until I did collectstatic - Django

My website was doing everything well and showing all the CSS until I ran collectstatic on it. Now everything is how it would look if CSS didn't exist. Is there any solution to this? Or is there some way I can delete the collectstatic to get back the previous thing?
I followed this tutorial to host this website: https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
Here's my settings.py(only the last bit where I set the static and the media stuff):
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATICFILES_DIRS = []
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
LOGIN_URL = '/main/user_login/'
Okay, so as you mentioned it stopped working after you ran collectstatic command.
collectstatic command makes Django looks for all static files in your apps and collects them in a single directory which is STATIC_ROOT. (In production it needs a single directory for all the static files)
Put the directories containing your static files into the STATICFILES_DIRS.
You also have to include your static urls in your urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [your paths go here]
urlpatterns += staticfiles_urlpatterns()
After including your static directories into the STATICFILES_DIRS array and including the static urls in your urls.py, use the command collectstatic and then it should work.

Gunicorn with Django giving a problem with static files

Got a Django project named django_server. When I run
python manage.py runserver
the page shows up as expected
Then, if I run
gunicorn django_server.wsgi:application --bind 0.0.0.0:8000
The page shows without styling
Checking the console, can see the following errors for both .css and .js files
The resource from
“http://0.0.0.0:8000/static/....css” was blocked
due to MIME type (“text/html”) mismatch (X-Content-Type-Options:
nosniff).
In the terminal where the gunicorn command was executed, can read
NOT FOUND: /static/rest_framework/css/bootstrap.min.css
NOT FOUND: /static/rest_framework/css/bootstrap-tweaks.min.css
...
In settings.py I mention
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
This is the folder structure
Checked the permissions in static folder (ls -l)and they show as
drwxrwxr-x 4 tiago tiago 4096 jun 2 15:49 static
Checking the permissions in the files where the problem happens and
Added also to settings.py
import mimetypes
mimetypes.add_type("text/css",".css",True)
mimetypes.add_type("text/javascript",".js",True)
But the error remains.
You need to run python manage.py collectstatic.
On your settings.py I recommend you to use whitenoise to serve your files.
1) pip install whitenoise
2) Add STATICFILES_STORAGE on settings.py
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
3) Add to your MIDDLEWARE on settings.py
`MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.security.SecurityMiddleware',
...
]

Static files not rendering in Django 2.2 when debug disabled

In Django 2.2, when I have DEBUG=True, all my static files render fine. But when I set DEBUG=False to test my production settings, all static file URLs suddenly return 404 errors.
I have a project structure like:
myproject/
myproject/
settings.py
urls.py
manage.py
static/
thumbnails/
image.png
My relevant static settings in settings.py:
STATIC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'static'))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
ROOT_URLCONF = 'myproject.urls'
STATIC_URL = '/static/'
DEBUG = False
And my urls.py looks like:
import os
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Why does a url like http://localhost:8000/static/thumbnails/image.png work fine when debug is on, but return a 404 when debug is off?
In production, you should run python manage.py collectstatic, and actually serve your static files from somewhere.
If you look at the docs for static files, you'll see
Serving the files
In addition to these configuration steps, you’ll also need to actually
serve the static files.
During development, if you use django.contrib.staticfiles, this will
be done automatically by runserver when DEBUG is set to True (see
django.contrib.staticfiles.views.serve()).
This method is grossly inefficient and probably insecure, so it is
unsuitable for production.
See Deploying static files for proper strategies to serve static files
in production environments.
You should set the STATIC_ROOT in you production settings to a folder on you web server, and configure your webserver to point your STATIC_URL to that folder. See here.
In your case, it's seems you have taken all these steps, except actually serving your static files. You can do this by pointing your web server to the correct folder, or serving you static files from a CDN or other solution. Here's how to do it using apache
Django was never meant to replace web servers. From the Django docs:
Django doesn’t serve files itself; it leaves that job to whichever Web server you choose.
This method is grossly inefficient and probably insecure, so it is unsuitable for production.
On localhost with DEBUG = TRUE it deploys the static file. While on production, you should use your web server(Apache, 'Nginx' etc) to deploy static files.
Just list the static directory in the configuration file of your web server. More detailed instructions regarding deployment can be found here

Unexpected directories and files while using collectstatic in django

This is my django project, there is two apps; polls and study
This is the setting of my static file settings.
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"study","static","HScard"),
)
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
I expected the 'python manage.py collectstatic' in the shell would copy static files to "staticfiles" from only in "study/static/HSCard"(due to STATICFILES_DIRS above).
However, "collectstatic" copied unexpected files below.
enter image description here
Why are the files in admin and polls copied to staticfiles?? besides the files in admin folder were from here (a single example):
Copying 'C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\static\admin\js\vendor\xregexp\xregexp.min.js'
Why does 'collectstatic' working like this and how can I fix it as I expected?
The version of django using is 2.0.7.
Thank you.
The problem is due to the default Staticfiles Finders settings:
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
The AppDirectoriesFinder will look through your apps listed in your INSTALLED_APPS setting. If there are files such as admin/static/, which are included in the admin by default, then they will also be found by collect_static. Your choices are to either:
Remove apps from INSTALLED_APPS (obviously they won't work any more, but they won't contribute static files either)
Add the STATICFILES_FINDERS setting as above, but without the AppDirectoriesFinder setting. Then Django will only collect staticfiles that you have explicitly mentioned in STATICFILES_DIRS

Location of static files when creating a Django exe using pyinstaller

I have a Django project with the following structure:
root
videos
static
templates
and the STATIC_URL setting in settings.py is STATIC_URL = '/static/'
I managed to use pyinstaller to create a windows executable from manage.py. I can start the Django server but I can't figure out where to put the static files.
When I first started the server it could not find the templates as well, it searched for them in : 'root\django\contrib\admin\templates\videos\' I copied the templates to this folder and it worked. But I can't figure out where to put the static files. I tried putting them in 'root\django\contrib\admin\static' to recreate the original structure. But it seems it doesn't search for them there...
Anyone knows where the static files should go? Or how to define the place where a bundled pyinstaller exe will look for them ?
please see https://docs.djangoproject.com/en/1.10/howto/static-files/
in your urls.py file, you should add something like blew
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^login$', login, name='login'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
and in your app.spec file, add datas
datas=[('xxx/templates','xxx/templates'),
('xxx/static','xxx/static')],
I think I figured this one out. Like you, I was having the same issue where I could package and build my Django project with pyinstaller, but the static files could not be found when running the project from the built executable. Everything was working fine when I would run the project with manage.py, but this was a head scratcher.
The solution that worked for me was running the collectstatic function and then serving my static files from that directory instead of the app/static/app directory.
If you aren't familiar with collectstatic it essentially searches your project directory for all of the static files in your apps and puts them in a folder on your top level directory that you specify in your settings file.
Here's how to run it.
Here's a link to its documentation.
Now my top-level directory looked like this.
site
app
admin.py
apps.py
models.py
views.py
site
asgi.py
settings.py
urls.py
wsgi.py
media
media files
staticfiles
static files I want to serve (css, js, etc)
In my settings file I specified my static file settings like this...
STATIC_URL = '/staticfiles/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'app\\static\\app')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
Then in my urls.py file I included the staticfiles directory like this...
(Note this is the urls.py file in the main site directory not in the app directory if you made one in there)
from django.contrib import admin
from django.conf import settings
from django.urls import include, path
from django.conf.urls.static import static
urlpatterns = [
path('', include('app.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
In my spec file I was able to add the folder like this...
datas=[('..\\site\\staticfiles\\', '.\\staticfiles\\')]
And then in my html file I was able to use the static files like this...
<script src="{% static 'app/static.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'app/static.css' %}">
Hopefully this helps some people if they've run into the same problem. Also as a reminder be sure to run collectstatic before you build especially if you've modified or changed any of your static files.
python manage.py collectstatic
Cheers!
First make sure that django.contrib.staticfiles is included in your INSTALLED_APPS in settings.py. Then have to insert in your settings.py for example this one:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
I hope definition of BASE_DIR you have in the top of settings.py. BASE_DIR points to a folder, where your manage.py file exists. So if you would have static files in the same dir, then you leave above setting as it is. If not, let's say in the same dir, next to manage.py you will have folder named app, then your settings should look like:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "app/static"),
]
And you can even run:
python manage.py collectstatic
To get admin static files into your static directory.
Hope that helps.
This looks like it might be an issue with where the PyInstaller packed python script looks for static files. They are placed in a temporary folder and need to be accessed by an absolute path. Check out this issue: Bundling data files with PyInstaller (--onefile)

Categories