Issue with static files when deploying Django app to Heroku - django

My project folder looks this:
├── Procfile
├── core
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-39.pyc
│   │   └── views.cpython-39.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── inspirationSources.txt
├── manage.py
├── package-lock.json
├── package.json
├── react-frontend
│   ├── README.md
│   ├── build
│   │   ├── asset-manifest.json
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   ├── logo512.png
│   │   ├── manifest.json
│   │   ├── robots.txt
│   │   └── static
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   ├── logo512.png
│   │   ├── manifest.json
│   │   └── robots.txt
│   └── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── assets
│   ├── components
│   ├── hooks
│   ├── index.css
│   └── index.js
├── requirements.txt
├── spotify
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-39.pyc
│   │   ├── admin.cpython-39.pyc
│   │   ├── apps.cpython-39.pyc
│   │   ├── cluster.cpython-39.pyc
│   │   ├── credentials.cpython-39.pyc
│   │   ├── models.cpython-39.pyc
│   │   ├── urls.cpython-39.pyc
│   │   ├── util.cpython-39.pyc
│   │   └── views.cpython-39.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── cluster.py
│   ├── credentials.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── models.py
│   ├── templates
│   ├── tests.py
│   ├── urls.py
│   ├── util.py
│   └── views.py
├── spotifycluster
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-39.pyc
│   │   ├── settings.cpython-39.pyc
│   │   ├── urls.cpython-39.pyc
│   │   └── wsgi.cpython-39.pyc
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── tutorialSources.txt
When I deploy with git push heroku main it seems to be fine but when I open the app in browser using the complementary url, I get the following errors on screen (debug mode is on):
TemplateDoesNotExist at /
build/index.html
Request Method: GET
Request URL: https://nameless-taiga-02413.herokuapp.com/
Django Version: 3.1.7
Exception Type: TemplateDoesNotExist
Exception Value:
build/index.html
Exception Location: /app/.heroku/python/lib/python3.9/site-packages/django/template/loader.py, line 19, in get_template
Python Executable: /app/.heroku/python/bin/python
Python Version: 3.9.4
Python Path:
['/app/.heroku/python/bin',
'/app',
'/app/.heroku/python/lib/python39.zip',
'/app/.heroku/python/lib/python3.9',
'/app/.heroku/python/lib/python3.9/lib-dynload',
'/app/.heroku/python/lib/python3.9/site-packages']
Server time: Fri, 30 Apr 2021 10:08:26 +0000
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.filesystem.Loader: /app/react-frontend/build/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /app/.heroku/python/lib/python3.9/site-packages/django/contrib/admin/templates/build/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /app/.heroku/python/lib/python3.9/site-packages/django/contrib/auth/templates/build/index.html (Source does not exist)
I have the following settings in my settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
Also I have whitenoise in my middleware list
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
...]
The templates section in settings.py looks as follows
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'react-frontend')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I expected that Heroku would be able to find the static folder based on the STATIC_DIRS variable but that doesn't seem to be the case. Any clue what's going on here?

So actually it was a really stupid mistake. react-frontend was a broken submodule and I needed to fix that by making sure .git/config didn't have submodules and removing react-frontend from the cache (No submodule mapping found in .gitmodules for path and missing .gitmodules file). Commit and pushed again and it worked...

if your DEBUG is set to False Django din't handle STATIC FILES. Heroku provide some configuration to serve STATIC FILES
STEP-1 : install whitenoise
$ pip install whitenoise
STEP-2 : check in settings.py whitenoise middleware by default it available in MIDDLEWARE if it's not that add it.
MIDDLEWARE = (
'whitenoise.middleware.WhiteNoiseMiddleware',
...)
STEP-3: add this in your settings.py
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Related

Gunicorn Nginx Django static files: images not shown

I've been digging through articles and posts about this subject but can't seem to get my images to load. For some reason the CSS on my pages seems to load just fine.
settings.py
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
also I tried
STATIC_ROOT = '/var/www/myname/'
template
<img src="{% static 'picture.jpg' %}" class="img-fluid">
NGINX
/etc/nginx/sites-enabled/django_project
server {
listen 80;
server_name mywebsite.com;
location /static/ {
alias /var/www/myname/static/;
}
}
directories
/var/www/myname
└── static
└── admin
├── css
│   ├── styles1.css
│   └── styles2.css
├── images
│   ├── picture.jpg
│   └── python.jpg
└── js
└── scripts.js
/home/myname/myprojectdir
├── django_project
│   ├── django_project
│   │   └── __pycache__
│   ├── etc
│   ├── index
│   │   ├── migrations
│   │   │   └── __pycache__
│   │   ├── __pycache__
│   │   └── templates
│   │   └── index
│   │   └── backups
│   ├── __pycache__
│   └── static
│   ├── admin
│   │   ├── css
│   │   │   └── vendor
│   │   │   └── select2
│   │   ├── fonts
│   │   ├── images
│   │   │   └── gis
│   │   ├── img
│   │   │   └── gis
│   │   └── js
│   │   ├── admin
│   │   └── vendor
│   │   ├── jquery
│   │   ├── select2
│   │   │   └── i18n
│   │   └── xregexp
│   ├── images
│   └── index
│   ├── css
│   ├── images
│   └── js
├── myname_env
│   ├── bin
│   └── lib
│   └── python3.10
│   └── site-packages
└── static
└── admin
├── css
│   └── vendor
│   └── select2
├── fonts
├── img
│   └── gis
└── js
├── admin
└── vendor
├── jquery
├── select2
│   └── i18n
└── xregexp
I've tried installing the static files in other directories, etc, to see what works but I'm not having any luck whatsoever. I had the static files in the project but after reading that's not a good practice I put them into var/www.
can you add this into nginx conf and try:
location /images/ {
alias /var/www/myname/static/images;
}

List apps of a django project

I'm completely new for django and I'd want to list the apps of a django project, for example:
FeinCMS
I know that startapp creates the directory structure for an app. I wonder if there is either a function or a file to get the app list.
For example taking FeinCMS as an example, the repo contains:
feincms
├── AUTHORS
├── CHANGELOG.rst
├── CONTRIBUTING.rst
├── docs
│   ├── admin.rst
│   ├── advanced
│   ├── conf.py
│   ├── contenttypes.rst
│   ├── contributing.rst
│   ├── deprecation.rst
│   ├── extensions.rst
│   ├── faq.rst
│   ├── images
│   ├── index.rst
│   ├── installation.rst
│   ├── integration.rst
│   ├── Makefile
│   ├── medialibrary.rst
│   ├── migrations.rst
│   ├── page.rst
│   ├── releases
│   ├── settings.rst
│   ├── templatetags.rst
│   └── versioning.rst
├── feincms
│   ├── admin
│   ├── apps.py
│   ├── content
│   ├── contents.py
│   ├── context_processors.py
│   ├── contrib
│   ├── default_settings.py
│   ├── extensions
│   ├── __init__.py
│   ├── _internal.py
│   ├── locale
│   ├── management
│   ├── models.py
│   ├── module
│   ├── shortcuts.py
│   ├── signals.py
│   ├── static
│   ├── templates
│   ├── templatetags
│   ├── translations.py
│   ├── urls.py
│   ├── utils
│   └── views
├── LICENSE
├── MANIFEST.in
├── README.rst
├── setup.cfg
├── setup.py
└── tests
├── cov.sh
├── manage.py
├── requirements.txt
├── testapp
└── tox.ini
How can I use django to list the apps in the repo?
settings.INSTALLED_APPS is the list of apps. You can start a django shell (manage.py shell) to query the settings:
from django.conf import settings
print(settings.INSTALLED_APPS)
>>> ['user', 'django.contrib.auth', 'django.contrib.sites', ...]
Query django.apps ...
from django.apps import apps
for app in apps.get_app_configs():
print(app, app.name, app.label)
Results in ...
<ContentTypesConfig: contenttypes> django.contrib.contenttypes contenttypes
<AdminConfig: admin> django.contrib.admin admin

Eclipse: unresolved import

Eclipse Neon (4.6.0).
PyDev for Eclipse 5.1.2.201606231256
I have created a Django project:
File / New / Project / PyDev Django project
Selected "Add project directory to the PYTHONPATH".
Now I have this folder structure.
(django_comments) michael#ThinkPad:~/workspace/formsets$ tree
.
└── formsets
├── db.sqlite3
├── formsets
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   ├── settings.cpython-35.pyc
│   │   ├── urls.cpython-35.pyc
│   │   └── wsgi.cpython-35.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── home_page
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-35.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-35.pyc
│   │   ├── __init__.cpython-35.pyc
│   │   ├── models.cpython-35.pyc
│   │   └── views.cpython-35.pyc
│   ├── templates
│   │   └── home_page
│   │   └── home_page.html
│   ├── tests.py
│   └── views.py
└── manage.py
In prjoect properties in PyDev-PYTHONPATH at the tab Source Folders I have:
/${PROJECT_DIR_NAME}
In home_page/views.py I have created HomePageView. And in urls.py I would like to import it:
from home_page.views import HomePageView
The problem is:
1) HomePageView is underlined with red line. Error is Unresolved import: HomePageView.
2) Code completion is not working.
By the way, if I run the project, it works. That HomePageView shows what was expected.
Could you help me understand what have I done wrongly.
Try to add a path to the directory where your manage.py file is located. So I'm guessing it to add:
/${PROJECT_DIR_NAME}/formsets

django startproject using project template gives template TemplateSyntaxError

I am working on a project to customize the startproject command to create django projects from project_template, see below:
bootstrap/
├── __init__.py
├── conf
│   ├── __init__.py
│   └── project_template
│   ├── manage.py
│   ├── project_name
│   │   ├── __init__.py
│   │   ├── apps
│   │   │   ├── __init__.py
│   │   │   └── example
│   │   │   ├── __init__.py
│   │   │   ├── admin.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   ├── urls.py
│   │   │   └── views.py
│   │   ├── contrib
│   │   │   └── __init__.py
│   │   ├── settings
│   │   │   ├── __init__.py
│   │   │   ├── base.py
│   │   │   ├── development.py
│   │   │   └── production.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── requirements
│   │   ├── base.txt
│   │   ├── development.txt
│   │   └── production.txt
│   ├── requirements.txt
│   ├── static
│   │   ├── js
│   │   │   └── base.js
│   │   ├── scss
│   │   │   └── base.scss
│   │   └── vendor
│   │   └── README
│   └── templates
│   ├── 404.html
│   ├── 500.html
│   ├── base.html
│   └── example
│   ├── base.html
│   └── index.html
└── management
├── __init__.py
└── commands
├── __init__.py
└── startproject.py
this is the startproject.py
import os
import grabone as go
from django.core.management.commands.startproject import Command as StartprojectCommand
EXTENSIONS = ['py', 'txt', 'html', 'scss', 'css', 'js', 'bowerrc', 'rst']
class Command(StartprojectCommand):
def handle(self, project_name=None, target=None, *args, **options):
options['extensions'] += EXTENSIONS
return StartprojectCommand.handle(self, project_name=project_name, target=target, *args, **options)
def handle_template(self, template, subdir):
if template is None:
return os.path.join(go.__path__[0], 'conf', subdir)
return StartprojectCommand.handle_template(self, template, subdir)
When I run django-admin startproject test1 it creates the project folder etc etc, but it will try to parse the html templates and give me an error:
django.template.base.TemplateSyntaxError: 'staticfiles' is not a valid tag library: Template library staticfiles not found, tried django.templatetags.staticfiles
This is what the template looks like:
{% load staticfiles %}
<html>
...
</html>
This is what the INSTALLED_APPS in setting look like:
DJANGO_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
)
THIRD_PARTY_APPS = (
'django_extensions',
'pipeline',
# Add third party apps here
)
LOCAL_APPS = (
# Add local apps here
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Some how the content in the settings is not being executed though...
removed html from
EXTENSIONS = ['py', 'txt', 'html', 'scss', 'css', 'js', 'bowerrc', 'rst']
Worked.

django, compressor and foundation scss

Hi I am trying to integrate foundation scss into django using django-compressor's precompiler, the project looks like this:
├── manage.py
├── requirements.txt
├── static
│   ├── config.rb
│   ├── humans.txt
│   ├── index.html
│   ├── javascripts
│   │   ├── foundation
│   │   │   ├── foundation.alerts.js
│   │   │   ├── foundation.clearing.js
│   │   │   ├── foundation.cookie.js
│   │   │   ├── foundation.dropdown.js
│   │   │   ├── foundation.forms.js
│   │   │   ├── foundation.joyride.js
│   │   │   ├── foundation.js
│   │   │   ├── foundation.magellan.js
│   │   │   ├── foundation.orbit.js
│   │   │   ├── foundation.placeholder.js
│   │   │   ├── foundation.reveal.js
│   │   │   ├── foundation.section.js
│   │   │   ├── foundation.tooltips.js
│   │   │   └── foundation.topbar.js
│   │   └── vendor
│   │   ├── custom.modernizr.js
│   │   ├── jquery.js
│   │   └── zepto.js
│   ├── MIT-LICENSE.txt
│   ├── robots.txt
│   ├── sass
│   │   ├── app.scss
│   │   ├── normalize.scss
│   │   └── _settings.scss
│   └── stylesheets
│   ├── app.css
│   └── normalize.css
├── templates
│   ├── 404.html
│   ├── 500.html
│   ├── admin
│   │   └── base_site.html
│   └── base.html
└── weddings
├── __init__.py
├── __init__.pyc
├── local_settings.py
├── local_settings.pyc
├── settings.py
├── settings.pyc
├── urls.py
├── urls.pyc
└── wsgi.py
and the precompiler looks like this in settings.py
COMPRESS_PRECOMPILERS = (
('text/x-scss', 'sass --scss --compass {infile} {outfile}'),
)
And when I run it with nginx + uwsgi, I get the following error:
Syntax error: File to import not found or unreadable: foundation/foundation-global.
Load paths:
/etc/uwsgi/vassals
/etc/uwsgi/vassals/sass
/srv/www/weddings/gems/compass-0.12.2/frameworks/blueprint/stylesheets
/srv/www/weddings/gems/compass-0.12.2/frameworks/compass/stylesheets
Compass::SpriteImporter
/srv/www/weddings/gems/bourbon-3.1.1/app/assets/stylesheets
/srv/www/weddings/gems/bourbon-3.1.1/app/assets/stylesheets
on line 2 of /srv/www/weddings/weddings/static/sass/_settings.scss
from line 2 of /srv/www/weddings/weddings/static/sass/app.scss
Use --trace for backtrace.
I suspect it's not reading the config.rb or the settings in config.rb is wrong:
http_path = "/"
css_dir = "stylesheets"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"
As you have a config.rb file, you have a Compass project.
Compass projects are supposed to be compiled with the compass command line tool, not sass command line tool.
As you have already discovered, compilation should be launched from insie the project folder. But it's a bad idea to hardcode the path into settings.py as it makes your project unportable.
Instead of a hardcoded path, you should use os.path.dirname(os.path.realpath(__file__)) to discover current script's path. To change the folder relative to settings.py, use os.path.join() like this (adjust as necessary, you can use ..):
os.path.join(os.path.dirname(os.path.realpath(__file__)), "static")
Also, you may already have PROJECT_DIR var in your settings.py. Use it to make this line cleaner.
A little improvement to #James Lin
COMPRESS_PRECOMPILERS = (
# ('text/x-scss', 'django_libsass.SassCompiler'),
# ('text/x-scss', 'sass --scss {infile} {outfile}'),
('text/x-scss', 'sass --scss --compass {infile} {outfile}'),
)
My current work around is to run the sass command in the folder where ocnfig.rb is located
COMPRESS_PRECOMPILERS = (
('text/x-scss', 'cd /srv/www/project/name/static && sass --scss --compass {infile} {outfile}'),
)