Css is not reflected when deploying django on heroku - django

I wrote the code in settings.py as below, but the css was not reflected. I also ran $ heroku run python manage.py collectstatic, but when I looked at heroku run bash, there were no static files. Please tell me how to deal with it.
settings.py
from pathlib import Path
import os
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
]
from socket import gethostname
hostname = gethostname()
if "User-MacBookAir.local" in hostname:
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
ALLOWED_HOSTS = ['*']
else:
DEBUG = False
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES = {
'default': dj_database_url.config()
}
ALLOWED_HOSTS = ['.herokuapp.com']
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)

Related

PostgreSQL and My Django app on heroku is not synching

I have a django made app on heroku and I want change the database there from sqlite to postgreSQL.
I have changed the code in setting.py as follows however the data in my local sqlite is still uploaded to heroku.
from socket import gethostname
hostname = gethostname()
if "MY-COMPUTER-NAME" in hostname: #my computer name
# debug
# DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
ALLOWED_HOSTS = ['*']
else:
# online
# DEBUG = False
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES = {
'default': dj_database_url.config()
}
ALLOWED_HOSTS = ['*']
My commands to deploy
git add -A
git commit -m "Change"
git push heroku master
heroku ps:scale web=1
heroku run python manage.py migrate
heroku open
this is a full code of srtting.py
import os
import django_heroku
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ":)"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog",
]
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",
]
ROOT_URLCONF = "personal_portfolio.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": ["personal_portfolio/templates/"],
"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",
]
},
}
]
WSGI_APPLICATION = "personal_portfolio.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
from socket import gethostname
hostname = gethostname()
if "MY-COMPUTER-NAME" in hostname: #my computer name
# debug
# DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
ALLOWED_HOSTS = ['*']
else:
# online
# DEBUG = False
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES = {
'default': dj_database_url.config()
}
ALLOWED_HOSTS = ['*']
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation"
+ ".UserAttributeSimilarityValidator"
},
{
"NAME": "django.contrib.auth.password_validation"
+ ".MinimumLengthValidator"
},
{
"NAME": "django.contrib.auth.password_validation"
+ ".CommonPasswordValidator"
},
{
"NAME": "django.contrib.auth.password_validation"
+ ".NumericPasswordValidator"
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/' # css
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
django_heroku.settings(locals())
try:
from .local_settings import *
except ImportError:
pass
if not DEBUG:
SECRET_KEY = os.environ['SECRET_KEY'] #new
import django_heroku
django_heroku.settings(locals())

Why are some of my photos missing after I re-deploy heroku even though I have s3 set up

So when I go to re-deploy my heroku, some of my profiles are missing photos, and the same ones every single time. When I upload a user photo, I can see a copy of it being put into my AWS bucket. And it uploads and shows up. But when I re-deploy, it's gone. Why is this happening?
settings.py
STATIC_URL = '/static/'
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#Settings for django-bootstrap3
BOOTSTRAP4 = {
'include_jquery' : True,
}
#S3 BUCKETS CONFIG
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

Running collectstatic from Heroku runs successfully, but fails to push the files to AWS, run locally it's successful

I'm trying to run a basic django app from Heroku using S3 to serve both static and media files.
When I run the server locally with python3 manage.py collectstatic the static files are collected and placed into a newly created /static/ folder in my S3 bucket.
When I run heroku run python3 manage.py collectstatic I am told that the static files have been collected and copied to /app/staticfiles (on build with collectstatic not disabled it's collected and copied to /tmp/build_[id]/staticfiles). Nothing is added to my S3 bucket; looking at the app filestructure on Heroku there is no folder /app/staticfiles; the app has no folder called /staticfiles; and I only have one S3 bucket, so I'm not accidentally pushing to the wrong bucket. Finally, I've quadruple checked that the dev and prod environment settings match (where appropriate).
My hunch is that django.contrib.staticfiles has a very strong opinion about where the static files should end up and is overriding my settings for aws (aws_settings.py) once in production. Any pointers about how to resolve this, gratefully received!
settings.py
import os
import dj_database_url
import dotenv
import django_heroku
BASE_DIR = os.path.dirname(
os.path.dirname(
os.path.abspath(__file__)))
dotenv_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(dotenv_file):
#DEV_ENV
dotenv.load_dotenv(dotenv_file)
os.environ['ENVIRONMENT']='DEV'
from .envsettings.dev_settings import *
elif os.getenv('TEST_ENV', None):
#TEST_ENV
os.environ['ENVIRONMENT']='TEST'
from .envsettings.test_settings import *
else:
os.environ['ENVIRONMENT']='PROD'
from .envsettings.prod_settings import *
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp.apps.MyAppConfig',
'accounts.apps.AccountsConfig',
'storages',
'django_clamd',
]
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',
]
ROOT_URLCONF = 'myapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'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',
],
},
},
]
WSGI_APPLICATION = 'myapp.wsgi.application'
#ugly hack, probably a better way
if os.environ['ENVIRONMENT']=='PROD':
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
DATABASES['default'].update(dj_database_url.config(conn_max_age=500))
django_heroku.settings(locals())
dev_settings.py
import os
import dotenv
SECRET_KEY='shhhh'
DEBUG = True
ALLOWED_HOSTS = ['*',]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myapp',
'USER': 'user',
'PASSWORD': 'admin',
'HOST': 'localhost',
'PORT':'',
}
}
from .aws_settings import *
prod_settings.py
import os
from .aws_settings import *
SECRET_KEY = os.environ.get('SECRET', '')
DEBUG = False
ALLOWED_HOSTS = ['myapp.herokuapp.com',]
aws_settings.py
import os
BASE_DIR = os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.abspath(__file__))))
#S3 settings
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME', '')
AWS_QUERYSTRING_AUTH = False
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com'
AWS_LOCATION = 'static'
#static media settings
STATIC_URL = 'https://' + AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/static/'
MEDIA_URL = 'https://' + AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/media/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
STATIC_ROOT = 'static'
MEDIA_ROOT = 'media'
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',)
customstorages.py
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
location = settings.MEDIA_ROOT
This is the resolution
django_heroku.settings(locals()) was overriding my STATIC_URL. Replacing it with django_heroku.settings(locals(), staticfiles=False) was the main fix.
There was also the issue that my STATICFILES_DIRS contained my STATIC_ROOT (uncovered when running python3 manage.py runserver --insecure).

Using Webpack and Django settings

I try to use Django-webpack-loader with Django and VueJs but I am not able to use correct settings with my complex project setup to load webpack bundle. My project layout is
Endofyogavidya
--dist/bundle.js
manage.py
webpack.config.js
--Yogavidya
----apps
----static
--------main.js
--------App.Vue
----templates
----settings
------base.py
------development.py
In my settings.py
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
STATIC_URL = '/public/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, "dist"),
)
WEBPACK_LOADER = {
'DEFAULT': {
'CACHE': not DEBUG,
'BUNDLE_DIR_NAME': '',
'STATS_FILE': os.path.join(PROJECT_ROOT, 'webpack-stats.json'),
'POLL_INTERVAL': 0.1,
'TIMEOUT': None,
'IGNORE': ['.+\.hot-update.js', '.+\.map']
}
}
My index.html is not working because with these settings django tries collect my assets to '/home/ytsejam/public_html/endofyogavidya/yogavidya/settings/dist'. How can I adjust my folder settings correctly ?
Thanks
There is a nice tut on this. Follow the below link
https://medium.com/labcodes/configuring-django-with-react-4c599d1eae63
It is for ReactJS but hope you can relate it to the framework you are using.

Django static files on heroku

I deployed a django app to heroku, using "git push heroku master" which worked absolutely fine.
I then created a second app on the same git using "heroku create second-app -r staging'
and pushed using: git push staging master
when I open second-app, none of the static files are picked up or loaded (ie no css, js, or images work)
This is extremely confusing - please help!
my settings file is below
import os
import platform
import dj_database_url
DEBUG = True
TEMPLATE_DEBUG = DEBUG
# This should work for any deployment
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))
ADMINS = (
('me', 'me#gmailcom'),
)
MANAGERS = ADMINS
# LOCAL SETTINGS
if platform.system() in ['Windows', 'Darwin']:
#EV = 'LOCAL'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': BASE_DIR + '//db//db.sqlite3',
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.4/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'TIMEOUT': 86400,
'OPTIONS': {
'MAX_ENTRIES': 10000
},
}
}
# HEROKU SETTINGS
else:
#EV = 'HEROKU'
# DEBUG = False
DATABASES = {}
DATABASES['default'] = dj_database_url.config()
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.4/ref/settings/#allowed-hosts
# Allow all host headers
ALLOWED_HOSTS = ['*']
# Todo: ammar - update to Memcached
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'TIMEOUT': 86400,
'OPTIONS': {'MAX_ENTRIES': 10000},
}
}
TIME_ZONE = 'Europe/London'
LANGUAGE_CODE = 'en-gb'
SITE_ID = 1
USE_I18N = True
USE_L10N = True
USE_TZ = False
MEDIA_ROOT = ''
MEDIA_URL = '/media/'
STATIC_ROOT = ''
STATIC_URL = '/static/'
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
SECRET_KEY = '***'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'sm.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'sm.wsgi.application'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'mytemplates')
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
'django.contrib.admindocs',
'smcore',
'south',
'django.contrib.humanize',
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/getStarted/'
LOGOUT_URL = '/do_logout/'
# e-mail server
EMAIL_HOST_USER = '***#gmail.com'
EMAIL_HOST= 'smtp.gmail.com'
# EMAIL_PORT = 465
EMAIL_USE_TLS = True
EMAIL_HOST_PASSWORD = '***'
DEFAULT_FROM_EMAIL = '***#gmail.com'
SERVER_EMAIL = '***#gmail.com'
Update
I took a copy of the code and redeployed, which worked with the following updates to the settings:
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
(os.path.join(BASE_DIR,'smcore','static')),
)
STATICFILES_FINDERS = (
#'django.contrib.staticfiles.finders.FileSystemFinder',
#'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
I then branched my code (so I have master and staging) and synced new heroku remote into my staging branch. I then did a git push staging staging:master and it did a full upload; which has once again got me back to the same place... help!!!
Eventually solved this using the below in my urls file - from this question: Heroku - Handling static files in Django app
from <app> import settings
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
)
I have been dealing with the same problem too. I tried not to use the solution recommended by David since it seems to be used only in development (and not production) (See: Heroku static files not loading, Django)
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.
It seems that it's because you're using the staticfiles app without having set the STATIC_ROOT setting.
In comparison, my settings.py is something like:
# Static asset configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, '../myapp/static')
You should set the STATICFILES_DIRS too (note that my conf for this var is probably not the same than yours)
Then, push your code and try again.
If it still doesn't work, you can use this to debug :
https://devcenter.heroku.com/articles/django-assets#debugging
Since Django 1.3 you've been able to do the following
# only showing relevant imports
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns(
'',
# your urls go here
)
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
For Django 2.1.7, I did the following changes in order to work:
Added whitenoise to requirements.txt in addition to gunicorn
Project settings.py should have the following:
A) static settings:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
B) Add whitenoise to middleware:
MIDDLEWARE = [
.....
'whitenoise.middleware.WhiteNoiseMiddleware',
]
Finally commit and push your changes then deploy your app peacefully.