Location of django:
/usr/lib/python2.7/dist-packages/django/__init__.pyc
Location of django oscar:
/usr/local/lib/python2.7/dist-packages/oscar/__init__.pyc
My static files are not getting served properly. Above is my production setting. On my local machine, the locations are:
/usr/local/lib/python2.7/dist-packages/oscar/__init__.pyc
/usr/lib/python2.7/dist-packages/django/__init__.pyc
Could this be a possible reason for above problem?
Oscar ships its own set of static files in oscar/static/oscar When you deploy your site, you should run manage.py collectstatic so these files are also collected in your STATIC_ROOT
On DigitalOcean's Django app, your Nginx configuration is located in /etc/nginx/sites-enabled/django You may need to update the following section to point to the location of your STATIC_ROOT
# your Django project's static files - amend as required
location /static {
alias /home/django/django_project/django_project/static;
}
Related
I have a Django server running with nginx and gunicorn.
All static files are served correctly, only the admin page has no css, js, etc. .
I already ran collectstatic and restarted nginx and gunicorn.
Nothing changed.
What can I do?
Make sure to mention the locations of your staticfiles_dirs in settings.py. Also remember to mention the locations of your static files in a dynamic format instead of hard coding them in your html document.And make sure to load static in base.html.
Try using this sample code in your settings.py file:
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'templates'),
'/var/www/static/'
]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
After this use the following command in terminal:
python manage.py collectstatic
This should create the static folder and copy all the static objects inside
Running Django dev server has no problem: 'python manage.py runserver 9000'
But if use gunicorn, it complains:
'http://innovindex.com/pubmed/static/js/jquery-3.2.1.min.js '
Why gunicorn cannot find a local jquery but Django can?
The settings are:
settings.py (seems not related):
STATIC_URL = '/pubmed/static/'
in '/etc/nginx/sites-enabled/django'
location /static {
alias /home/django/innovindex/pubmed/static/;
}
And my app looks like this:
/home/django/innovindex
is where the 'manage.py' sits.
THANK YOU SO MUCH !!!
From Deploying static files in the Django documentation, you must run the collectstatic command in addition to setting the STATIC_ROOT setting.
First make sure that you're STATIC_ROOT is set to the correct path that matches your nginx config:
STATIC_ROOT = '/home/django/innovindex/pubmed/static/'
Note that this is an absolute path.
Then run:
python manage.py collectstatic
in your project directory.
This will copy all of your static files into /home/django/innovindex/pubmed/static/
I spent a lot of time trying to figure this out until I found that the below must be in your main urls.py. Just add those two lines.
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ...
urlpatterns += staticfiles_urlpatterns()
This si my settings.py about static in settings.py:
STATIC_ROOT = '/home/coat/www/site/app/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
"/usr/lib/python2.6/site-packages/django/contrib/admin/static/",
# This is Django admin default static files
)
I user django server:
./manager runserver
Then I open the URL: http://localhost:8000/static/admin/css/base.css
It works very well.
But a open http://localhost/static/admin/css/base.css
It print '404'
I had restart Nginx and uwsgi for many times, but it dosen't works.
First things first, this is nonono:
STATIC_ROOT = '/home/coat/www/site/app/static/'
Never hardcode absolute paths, you're just making your settings file less portable and probably killing kittens. Adapt this to your needs:
import os.path
import posixpath
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
# fix STATICFILES_DIRS too
Now, to your question. django.contrib.staticfiles is fantastic but probably a little confusing at first.
You must understand the collectstatic command:
Collects the static files into STATIC_ROOT. [...] Files are searched by using the enabled finders. The default is to look in all locations defined in STATICFILES_DIRS and in the 'static' directory of apps specified by the INSTALLED_APPS setting.
With runserver, staticfiles are served automatically, but in production mode (DEBUG=False, real HTTP server like Nginx), you should run collectstatic to (re)build STATIC_ROOT
STATIC_ROOT: is the root path where the HTTP server should serve static files from.
STATIC_URL: is the root URL where the HTTP server should serve static files to.
STATICFILES_DIRS: other static directories, in addition to each app's "static" subdirectory. Because django.contrib.admin is a normal app with a "static" folder, there is no need to specify it in the settings.
Conclusion: if STATIC_ROOT resolves to /home/coat/www/site/app/static/, and STATIC_URL is /static/, then you should:
Run collectstatic management command
Configure Nginx to serve /home/coat/www/site/app/static/ on /static/, ie.:
location ^~ /static/ {
alias /home/coat/www/site/app/static/;
}
Reload nginx
In development the runserver command does some magic to serve your static files. In production you need to configure NGinx to do it. There are two chapters in the Django documentation I recommend you read:
Serving static files in production
Serving files (Deployment)
Especially the last link explains how you have to configure your NGinx to serve your static files.
My django project contains a folder STATIC in which there are it's child folders css, images, js and swf. My web-site can not locate these files raising a 404 in the development server running on the terminal.
I have a settings_local.py file in which I have set the path such as (running on ubuntu 11.04)
STATIC_ROOT = '/home/zulaikha/dust.bin/my_project/static/'
STATIC_SERVE_PORT = 80
The sample settings-local.py file from the client suggest suggest so
# static root
STATIC_ROOT = 'C:/Program Files (x86)/XAMPP/htdocs/static'
STATIC_SERVE_PORT = 8080
I have seen some similar issues but all regard STATICFILES which I read was introduced in Django 1.3
Where am I wrong and how can I correct myself?
If you are indeed using django 1.2 then you must install django-staticfiles. If you do not see it in the included requirements.txt from your client then he either did not freeze it out into the file, or was not using that feature and instead was just pointing at it via apache or another production server.
Follow these instructions from the docs. Specifically the basic section:
https://docs.djangoproject.com/en/dev/howto/static-files/
You will need to add staticfiles to your installed app. You should also not need to manually add a url since the django should do it automatically with the runserver command.
Also verify that it works locally first by not running with sudo or a custom ip and port
According to your comments there are two options here:
Contact the programmer who wrote the code and ask him.
Rewrite static serving logic with
django-staticfiles (Django 1.2 is enough)
django.contrib.staticfiles and Django 1.3
In the simplest form, this is the solution to the problem. In project urls.py include the following lines
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT,
}),
)
When developing a Django application in debug mode, I serve static files using the following code:
if settings.DEBUG:
urlpatterns += patterns('',
(r'^m/(?P<path>.*)$', serve, {
'document_root' : os.path.join(os.path.dirname(__file__), "media")
})
)
I am using nginx as a front end to server my static files in production mode using the following nginx config:
location m/
{
root /path/to/folder/media/;
}
Which seems sub-optimal because I have to create a "m" folder in the media directory. I am wondering what everyone else's Django/nginx config files look like. Specifically, can you please cut-and-paste sections of nginx.confg and urls.py (settings.DEBUG == True)
Thanks.
Using Django 1.3 django.contrib.staticfiles will take care of serving everything for you during development. You don't need to do anything particular in the urls.py. I wrote a little guide for myself after the Django 1.3 update that covers the settings to use:
# idiom to get path of project
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
# url prefix for user uploaded files, stuff that django has to serve directly
MEDIA_URL = '/media/'
# url prefix for static files like css, js, images
STATIC_URL = '/static/'
# url prefix for *static* /admin media
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
# path to django-served media
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
# path used for collectstatic, *where the webserver not django will expect to find files*
STATIC_ROOT = '/home/user/public_html/static'
# path to directories containing static files for django project, apps, etc, css/js
STATICFILES_DIRS = (
os.path.join(PROJECT_PATH, 'static'),
)
# List of finder classes that know how to find static files in various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
# Required for all the magic
INSTALLED_APPS = (
'django.contrib.staticfiles',
)
Refer to the docs for details: http://docs.djangoproject.com/en/1.3/howto/static-files/.
I use nginx and uwsgi for serving django apps in production (I use runserver for development). I symlink my /static and /media folders (from my django project) into /var/www/vhosts/domain.com/html for nginx to find. You could also use the collectstatic command instead of symlinking. If it can't find a static file it falls back to uwsgi (which is running the django app).
Instead of uwsgi you could use fast-cgi, or proxy_pass or whatever you want. I prefer uwsgi because it has an incredible number of features and great performance. I run uwsgi as a daemon with: uwsgi --emperor '/srv/*/*.ini'. This is a fairly new option, it tells uwsgi to scan a given path for configuration files. When the emperor uwsgi daemon finds a configuration file it launches a new instance of uwsgi using the configuration found. If you change your configuration the emperor uwsgi daemon will notice and restart your app for you. You can also touch the config file to reload like with mod_wsgi, and it's really easy to setup new apps once you have everything configured initially.
The path conventions I follow are:
/srv/venv/ - virtualenv for project
/srv/venv/app.ini - configuration for uwsgi
/srv/venv/app.sock - uwsgi sock for django
/srv/venv/app.wsgi - wsgi file for uwsgi
/srv/venv/proj - django project
/srv/venv/proj/settings.py - project settings file
/srv/venv/proj/static - static files dir, linked into var/www/vhosts/domain.com/html
/srv/venv/proj/static/admin - admin static files, linked as well
/srv/venv/proj/media - media files dir
/var/www/vhosts/domain.com/html - base directory for nginx to serve static resources from
This is my nginx.conf:
location / {
root /var/www/vhosts/domain.com/html;
index index.html index.html;
error_page 404 403 = #uwsgi;
log_not_found off;
}
location #uwsgi {
internal;
include /etc/nginx/uwsgi_params;
uwsgi_pass unix:/srv/venv/app.sock;
}
My uwsgi ini file (you can also use xml/yaml/etc):
[uwsgi]
home = /srv/%n
pp = /srv/%n
wsgi-file = /srv/%n/%n.wsgi
socket = /srv/%n/%n.sock
single-intepreter = true
master = true
processes = 2
logto = /srv/%n/%n.log
You should also check out gunicorn, it has really nice django integration and good performance.
I'm putting this here in case someone wants an example of how to do this for Apache and WSGI. The question title is worded such that it's not just covering nginx.
Apache/WSGI Daemon
In my deployment, I decided to keep the database connection info out of the settings.py file. Instead I have a path /etc/django which contains the files with the database configuration. This is covered in some detail in an answer to another question. However, as a side effect, I can check for the presence of these files and the project being in a certain path to determine if this is running as a deployment, and in settings.py I define the settings IS_DEV, IS_BETA, and IS_PROD as True or False. Finding the project's directory from settings.py is just:
# Find where we live.
import os
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
Anything that needs a path into the project uses BASE_DIR. So in urls.py, I have at the end:
# Only serve static media if in development (runserver) mode.
if settings.IS_DEV:
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT,
'show_indexes': True}),
)
(I also have another URL in there that I use for UI testing and don't want on beta or production.)
This covers the development server case. For production, I just have to set the Apache configuration up to serve the static stuff. (This is an intranet application with low to medium load, so I don't have a lightweight webserver like lighttpd to serve the static stuff, contrary to the Django docs' recommendation.) Since I'm using Fedora Core, I add a django.conf file in /etc/httpd/conf.d that reads similar to:
WSGIDaemonProcess djangoproject threads=15
WSGISocketPrefix /var/run/wsgi/wsgi
Alias /django/static/ /var/www/djangoproject/static/
Alias /django/admin/media/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/
WSGIScriptAlias /django /var/www/djangoproject/django.wsgi
WSGIProcessGroup djangoproject
<Directory /var/www/djangoproject>
Order deny,allow
Allow from all
</Directory>
<Directory /usr/lib/python2.6/site-packages/django/contrib/admin/media>
Order deny,allow
Allow from all
</Directory>
IIRC, the key here is to put your Alias lines before your WSGIScriptAlias line. Also make sure that there's no way for the user to download your code; I did that by putting the static stuff in a static directory that is not in my Django project. That's why BASE_DIR gives the directory containing the Django project directory.
You can omit the WSGISocketPrefix line. I have it because the admin wants the sockets in a non-default location.
My WSGI file is at /var/www/djangoproject/django.wsgi (i.e. /django.wsgi in the Mercurial repository) and contains something like:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings'
os.environ['DB_CONFIG'] = '/etc/django/db_regular.py'
thisDir = os.path.dirname(__file__)
sys.path.append(thisDir)
sys.path.append(os.path.join(thisDir, 'djangoproject'))
sys.path.append(os.path.join(thisDir, 'lib'))
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
The nice thing about WSGI daemons is that you just have to touch django.wsgi to restart your Django WSGI daemon; you don't need to reload or restart the Apache server. This makes the admin happy.
Finally, since my /var/www/djangoproject is just a Mercurial repo, I have the following in /var/www/djangoproject/.hg/hgrc:
[hooks]
changegroup.1=find . -name \*.py[co] -exec rm -f {} \;
changegroup.2=hg update
changegroup.3=chgrp -Rf djangoproject . || true
changegroup.4=chmod -Rf g+w,o-rwx . || true
changegroup.5=find . -type d -exec chmod -f g+xs {} \;
changegroup.6=touch django.wsgi # Reloads the app
This clears Python bytecode, updates the working copy, fixes up all the perms, and restarts the daemon whenever a developer pushes into deployment, so anyone in the djangoproject group can push into it and not just the last one who added a file. Needless to say, be careful who you put in the djangoproject group.
zeekay sets STATIC_URL, STATIC_ROOT, STATICFILES_DIRS, STATICFILES_FINDERS and uses "django.contrib.staticfiles" and "django.core.context_processors.static" in his settings. I don't have those since my code dates back to Django 1.1 and don't use {{ STATIC_ROOT }}.
Hope this helps.