Django Static Files in Production Using Whitenoise - django

Firstly apologies for the length of this.
I have a django project running on Centos6 and Apache using a C-Panel plugin to install Django and I am trying to serve the static files in production.
My project uses Django 1.9 and I am trying to use Whitenoise to serve my static files.
My settings.py contains the following:
STATICFILES_STORAGE ='whitenoise.django.GzipManifestStaticFilesStorage'
STATIC_URL = '/static/'
STATIC_ROOT = STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'common-static'),
And this is my MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
)
This is the wsgi.py for my django app
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = get_wsgi_application()
And this is the one generated by the plugin:
import os
import sys
import site
vepath = '/home/mysite/virtualenv3.5/lib/python3.5/site-packages'
prev_sys_path = list(sys.path)
site.addsitedir(vepath)
sys.path.append('/home/mysite/djangosites/mysite')
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE","mysite.settings"
application = get_wsgi_application()
I have DEBUG = False in my settings.py.
When I run ./manage.py collectstatic the files are collected and if I run the server with 0.0.0.0:8000 the static files are found.
I tried add the following to both wsgi.py files but to no avail:
from whitenoise.django importDjangoWhiteNoise
application = DjangoWhiteNoise(application)
Any advice on how to solve this would be appreciated.

It's a late response but it might help other people searching for an answer.
You do NOT have to include 'django.middleware.security.SecurityMiddleware' when you're using 'whitenoise.middleware.WhiteNoiseMiddleware'.
Also, you don't need to make any changes in wsgi.py. Adding the middleware will take care of everything for you.

Related

No CSS in Admin panel in Azure App Service hosted Django APP

I cant figure out how to make Azure App Service use css for admin panel.
In settings.py I included these:
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
But somehow css is still not working for the admin panel.
How can I fix this? As far as I know Oryx which works under Azure App Service should automatically run
python manage.py collectstatic
Any ideas?
EDIT:
Installed apps
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'licenses_api',
]
There are something to check might help:
Click F12 on your Admin page to check if it is the 404 Not Found error.
Check the static files exist in your azure web app or not. You could see it in https://{your-web-app}.scm.azurewebsites.net/wwwroot/ site.
Check if your file structure match with the settings.py. Any spell error would make the static file not found.
If your file exists well, you should check if you use them correctly in your code like this answer. Here is how he use:
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)
Firstly try to add these code lines to
settings.py
STATIC_URL = '/static/'
if DEBUG:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
else:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Then import these lines to the
urls.py
from django.conf.urls.static import static
from django.conf import settings
from django.conf.urls import url
from django.views.static import serve
Finaly you have to add these lines to urlpatterns in
urls.py
url(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
url(r'^static/(?P<path>.*)$', serve,{'document_root': settings.STATIC_ROOT}),
(If you have not already created a static file please make sure to create one before you try this)
It's worked severl times for me and hope this will work for you too 😊

Error when setting DEBUG=False in Django Web application

I have developed my web application in Django Framework. I have also made the 404 and 500 Error pages and understand very much that, they can only work when DEBUG=False.
The problem now is that after setting DEBUG=False, my application which I have hosted on Heroku no longer shows. I am also using the whitenoise package for configuring my static files.
This are my settings.py as related to this issue
DEBUG = True
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
'whitenoise.middleware.WhiteNoiseMiddleware',
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATIC_URL = '/static/'
STATIC_ROOT = 'staticfile'
STATICFILES_DIRS = [BASE_DIR / "static"]
MEDIA_URL = '/media/'
MEDIA_ROOT = "media"
NOTE: I have collected staticfiles using the command heroku run python manage.py collectstaic
I was able to solve the issue. When I removed the whitenoise STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage', I noticed that i no longer got the error which read contact the administartor, and also my page was able to load and the 404 and 500 pages were loading correctly when i set the DEBUG=False
But I noticed that, the images where no longer showing. But I have a feeling that if I use aaws or cloudinary to host the images as well as server them, it should work perfectly.

Altering filepath after deployment to Heroku to access static files in views.py

My app is for students who provide their ID CNIC to get their certificates. A function download in views.py needs to
access an image (which is a blank certificate)
modify it by adding name and graduation date associated with cnic
save it as pdf
make it available for download
All works in development on localhost but when deployed to Heroku, the filepath to the image does not exist, which makes sense because the app is not local anymore - it accessible to anyone.
The question is, how do we find the new path to access Certificate_0001.jpg which was initially stored in certificates\static\certificates
Views.py
def download (request, date, name):
x = date.split(" ")
date = f"29 {x[3]} {x[4]}"
try:
image = Image.open("certificates\static\certificates\Certificate_0001.jpg")
except:
return HttpResponse ("image did not load")
font_type = ImageFont.truetype('arial.ttf', 70)
font_type_2 = ImageFont.truetype('arial.ttf', 35)
draw = ImageDraw.Draw(image)
draw.text(xy=(600, 740), text=name, fill=(0,102,0), font=font_type)
draw.text (xy=(330, 1230), text=date, fill=(0,102,0), font=font_type_2)
try:
image.save(f'certificates\static\certificates\{name}.pdf', "PDF", resolution=100.0)
except:
return HttpResponse("pdf did not save")
try:
with open(f'certificates\static\certificates\{name}.pdf', 'rb') as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = f'inline;filename=NFDP-{name}.pdf'
return response
except:
return HttpResponse("pdf did not load")
Settings.py
import os
import django_heroku
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
'whitenoise.middleware.WhiteNoiseMiddleware'
]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
django_heroku.settings(locals())
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
urls.py
from django.urls import path
from . import views
app_name = "certificates"
urlpatterns = [
path("", views.index, name="index"),
path("download/<str:name>/<str:date>", views.download, name="download")
]
wsgi.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nfdp.settings')
application = get_wsgi_application()
I found the solution. Actually, once a Django application is deployed to Heroku, all of the files are placed inside a new directory called app. You can also run heroku run bash and do cd app or go back one folder by cd .. and then cd app. Then you can see your files in app_name/static/app_name/my_file.xyz. Therefore, in order to access your staticfiles in views.py, you must change the file path so that it runs in production.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
##BASE_DIR = /app/ in production (heroku) but your project name in development (locally)
path = os.path.join(BASE_DIR, "certificates/static/certificates/Certificate_0001.jpg")

Django WSGI application could not be loaded

I found an error while re-running the django application and there are some solutions on stackoverflow,but it is not working for me .
django.core.exceptions.ImproperlyConfigured: WSGI application
'myapp.wsgi.application' could not be loaded; Error importing module.
Also checked Django Middle-Ware,All are installed and Properly Configured.
Following are the Middle-Ware i am using
'django_session_timeout.middleware.SessionTimeoutMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
MY DJANGO APPLICATION: myapp
WSGI_APPLICATION = 'myapp.wsgi.application'
Django Version: 2.1.7
Python : 3.7.1
WSGI.PY
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
application = get_wsgi_application()

Missing staticfiles manifest entry in Django deployment using Heroku

I am trying to deploy my webapp to heroku. I am using Django and the following is most of my settings.py file:
"""
Django settings for blog project on Heroku. For more info, see:
https://github.com/heroku/heroku-django-template
For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""
import os
import dj_database_url
import raven
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
try:
from .local_settings import *
except ImportError:
pass
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
# Disable Django's own staticfiles handling in favour of WhiteNoise, for
# greater consistency between gunicorn and `./manage.py runserver`. See:
# http://whitenoise.evans.io/en/stable/django.html#using-whitenoise-in-development
'whitenoise.runserver_nostatic',
'django.contrib.staticfiles',
'blogapp',
'homeapp',
'nimfksapp',
'omniclipapp',
#Heroku Sentry
'raven.contrib.django.raven_compat',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'blog.urls'
WSGI_APPLICATION = 'blog.wsgi.application'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'live-static', 'static-root')
STATIC_URL = '/static/'
# Extra places for collectstatic to find static files.
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "live-static", "media-root")
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
When running collectstatic locally the static files get collected fine and are served up on the web page. When I deploy the app to heroku (which automatically runs the collectstatic command for me) it throws up an "Internal Server Error (500)". I followed a recommendation on a similar SO page and added a sentry to the app through heroku and got a clearer error message:
ValueError/nimfks/ errorMissing staticfiles manifest entry for...
I tried changing (and removing) the STATICFILES_STORAGE without success. Removing it got me past the error but trying to display the actual static file (in this case an image) didnt work i.e. it wasnt loading.
I also tried changing the static settings to use PROJECT_ROOT instead of BASE_DIR and a lot of different configurations, all of which didnt work.
Am I missing something here? I cant seem to find an answer in the similar questions asked on SO.
EDIT
Answer:
Embarrasing as it is I want to keep this up since it might help someone else struggling with this. Issue in my case was that I was using .PNG in my html file instead of .png which was the real file extension. Didn't realize this was case sensitive. The real solution to this problem was essentially just having a sentry running that will catch these types of errors (see sentry docs). This is my final version of my static settings in the settings.py file:
import os
import dj_database_url
import raven
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
WSGI_APPLICATION = 'blog.wsgi.application'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'
# Extra places for collectstatic to find static files.
STATICFILES_DIRS = [
os.path.join(PROJECT_ROOT, 'static'),
]
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Try to comment the line
'django.contrib.staticfiles',
inside INSTALLED_APPS