Django won't recognize my static files on my dev machine - python

I've been tasked with fixing some aspects of a django 1.3 site, that runs on Apache/PostgreSql on the server. I'm trying to set it up on my development machine, with a virtual environment with postgres and the internal python developer server.
I managed to get the site running and reading from my local pg instance, but I can't get it to recognize my static files, which are stored in /site_media. The site will soon be rewritten to use django 1.6 and the proper /static folder but for now I need to fix this site.
I also tried running it with nginx and gnunicorn but the result is the same, the site displays but with no style and all references to files in the static dir give a 404. further inspection of the 404 reveals that django is trying to resolve the resources with its router.
Here are the relevant settings:
settings.py:
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = '/home/nico/src/df2/datos/site_media/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = 'http://localhost:8000/site_media/'
I also added the following config, to no avail:
INSTALLED_APPS = (
'django.contrib.staticfiles',
)
STATICFILES_DIRS = (
'/home/nico/src/df2/datos/site_media/',
)
STATIC_URL = 'http://localhost:8000/site_media'
nginx config file:
server {
server_name localhost;
access_log off;
location /site_media/ {
alias /home/nico/src/df2/datos/site_media;
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
If you need any other config please tell me.
I'd prefer to run this purely from the python server, but a solution with gunicorn/nginx is also fine

The fix was in adding a static handler to the urlpatterns variable:
from django.conf import settings
if settings.DEBUG:
# static files (images, css, javascript, etc.)
urlpatterns += patterns('',
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))

Related

Django/Nginx - 403 on Static Files

I've recently uploaded a django project to an Ubuntu 22.04 DigitalOcean droplet. Nginx, gunicorn, and postgres have all been set up without a hitch, but the static files are all being 403'd.
In both development and production, I never used collectstatic. The reason being, I always put all my static files in a static folder in the root of my project, so I figured I didn't have to do it. I'm not sure if collectstatic needs to be done in order for static files to be shown in production, but it seems that other people have still encountered this problem even when they've done collectstatic.
My project on the server is called pyapps, and in that folder there are the static and media folders. The static folder is further broken down into css, js, and images folders. The media folder is further broken down into photos, then folder by year, month, then day, all of which correlate to the time the photos were uploaded.
Below are my settings.py, urls.py and /etc/nginx/sites-available/ files' code.
settings.py
STATIC_URL = 'static/'
STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py
urlpatterns = [
...
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
/etc/nginx/sites-available/Car-terra
server {
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/djangoadmin/pyapps/Car-terra/static/;
}
location /media/ {
alias /home/djangoadmin/pyapps/Car-terra/media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
server {
if ($host = www.carterrarfw.online) {
return 301 https://$host$request_uri;
} # managed by Certbot
}
if ($host = carterrarfw.online) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name 146.190.210.138 carterrarfw.online www.carterrarfw.online;
return 404; # managed by Certbot
}
What I've Tried
chmod 777 on the static folder (in retrospect not a good choice, but it didn't work nonetheless)
changing root /home/djangoadmin/pyapps/Car-terra; to alias /home/djangoadmin/pyapps/Car-terra/static/ and media;
changing debug to True just to see if there was a difference (there wasn't)
I'm not sure if this is a problem with collectstatic, or if I'm telling nginx to look in the wrong place.
Is running collectstatic absolutely mandatory?
Thank you for your help.

Uploading and Downloading Files with Django and Nginx

I'm currently trying to upload some files using Django and it seems to be working for the most part. I'm at least able to see that the file is added to the specific model in the Django admin panel but I'm unable to open it. Additionally, whenever I try to get the URL of the file, I get forwarded to the Django error page with a nice error that says, [Errno 2] No such file or directory: 'media/some_file.csv'
Here is my file model :
class File(models.Model):
challenge = models.ForeignKey(Challenge, on_delete=models.CASCADE, default="")
file = models.FileField(default="", upload_to="media/")
def __str__(self):
return self.challenge.challenge_id
Settings.py :
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'server', 'static'),
os.path.join(BASE_DIR, '..', 'media'),
)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = 'media/'
Upload Function :
def uploadChallengeFile(request):
latestChallenge = Challenge.objects.last()
for file in request.FILES.items():
file_model = File(challenge=latestChallenge, file=file[0])
file_model.save()
data = {"data": [True]}
return JsonResponse(data, safe=False)
Download Function :
def downloadFile(request, challenge_id):
challenge = Challenge.objects.filter(challenge_id=challenge_id)
filename = File.objects.filter(challenge=challenge).values("file")[0]["file"]
content = open(File.objects.get(challenge=challenge).file.url).read()
response = HttpResponse(content, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
urls.py :
url(r'^api/start/download/(?P<challenge_id>[\w.#+-]+)/$', views.backendServices.downloadFile, name="download")
It seems like Django is saving the instance of the file but not actually storing it. Do I need to configure the nginx.conf to serve the files from the /media directory or do something else? Any help would be greatly appreciated.
Thanks
Generally you have to configure nginx to proxy pass requests to media/ and static/ to your django instances:
The following assumes your django service can be reached at http://django:8000, but more likely if you're not using docker (and it's not named django), it would be http://localhost:8000
location /static {
proxy_pass http://django:8000;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /media {
proxy_pass http://django:8000;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
Also, make sure when running in DEBUG mode (normally local dev) set the URL routes so django handles them
if settings.DEBUG:
from django.views.static import serve
from django.conf.urls.static import static
urlpatterns += [
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

django+nginx deployment not loading static files correctly

server {
listen 80;
server_name 13.xx.xx.xxx;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/studykarma/django-react-redux-base/src/;
}
location / {
include proxy_params;
include /etc/nginx/mime.types;
proxy_pass http://unix:/home/ubuntu/studykarma/django-react-redux-base/src/djangoreactredux.sock;
}
}
my nginx config file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static_dist'),
)
my settings.py
I have my static files in static_dist folder and my reactjs code in static
folder.
My static files are not loading and giving me 404,
If i change path to /static_dist/ then also i am getting empty content.
I am using this template: https://github.com/Seedstars/django-react-redux-base
About Nginx configuration
location /static/ {
root /home/ubuntu/studykarma/django-react-redux-base/src/;
}
This configuration tells Nginx that on accessing via say example.com/static/app.js, look app.js file inside src folder root, if you want static_dist, then the configuration change will be
location /static/{
root /home/ubuntu/studykarma/django-react-redux-base/src/path/to/static_dist/;
}
About Django configuration
Your Django settings is logically wrong,
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
Above settings tells django that you expect all your static files from STATICFILES_DIRS to STATIC_ROOT, the configuration is effective/used by django when you use collectstatic django manage command, which ineffect copies all your files from STATICFILES_DIRS to STATIC_ROOT( but this also means that, you have to point /static/ location nginx config to static_root instead of static_dist.
Use this,
location /static_root/ { root /home/ubuntu/studykarma/django-react-redux-base/src/static_r‌​oot/; }
it will work

Nginx looking for a different path than what is given Django static files url setting

I ran into very weird issue for which I could not find a reason. I have a django app with uWSGI as my app server and Nginx as our reverse proxy. My initial setting for the static url in Django are as below:
PROJECT_DIR = "/home/ubuntu/src/myapp"
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'staticfiles')
STATIC_URL = '/staticfiles/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
and what's there in the nginx conf is as below:
server {
listen 80;
server_name stg1.myapp.com
client_max_body_size 5G; # adjust to taste
access_log /var/log/nginx/myapp-access.log combined;
error_log /var/log/nginx/myapp-error.log;
location /media {
alias /home/ubuntu/src/myapp/media/; # your Django project's media files - amend as required
}
location /static {
alias /home/ubuntu/src/myapp/staticfiles/;
}
location / {
uwsgi_pass django;
uwsgi_read_timeout 600s;
uwsgi_buffering off;
uwsgi_send_timeout 600s;
proxy_read_timeout 600s;
include /home/ubuntu/src/myapp/uwsgi_params;
}
}
Now, when I was trying to access the server I was getting this error for the static files:
2016/12/13 20:33:03 [error] 30533#0: *194 open() "/home/ubuntu/src/myapp/staticfiles/files/css/base.css" failed (2: No such file or directory), client: 172.31.4.166, server: stg.myapp.com, request: "GET /staticfiles/css/base.css HTTP/1.1", host: "stg.myapp.com", referrer: "http://stg.myapp.com/profile/user1"
Collectstatic copied all the files in the given STATIC_ROOT location. But the path actually searched was - STATIC_ROOT/files.
When I changed the STATIC_ROOT to
STATIC_ROOT = os.path.join(PROJECT_DIR, 'staticfiles/files')
it worked. I am still clueless about why the directory staticfiles/files was being looked for and not just the staticfiles directory as given in nginx conf. Where should I be looking for a possible reason?
EDIT - I had restarted nginx service whenever there was a change done there. So no issues there.
I found the reason.
STATIC_URL = '/staticfiles/' is creating issue. It has to be
STATIC_URL = '/static/'.
The earlier one appends the files in the path on request which was causing my issue.
Cannot find the directory files anywhere in your first set up. [I have not privileges to comment yet].
The set up looks good for me, maybe you just forget to restart Nginx when you modified the configuration file.
Refer link at STATIC_ROOT in Django on Server
Also Static Root and Static Url confusion in Django

Static Files not being displayed in Production

EDITED TO SHOW UPDATED CONFIGURATION
No static files are being shown in Production. Files are showing correctly in Development
settings.py
BASE_DIR = os.path.dirname(__file__)
STATIC_ROOT = '/opt/soundshelter/static/'
print "Base Dir: " + BASE_DIR #this returns /opt/soundshelter/soundshelter/soundshelter
print "Static Root: " + STATIC_ROOT #this returns /opt/soundshelter/static/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
) #/opt/soundshelter/soundshelter/soundshelter/static
Files are being called in the applications with
<link href="{% static "css/portfolio-item.css" %}" rel="stylesheet">
Using Nginx and Gunicorn.
Nginx config:
server {
server_name 46.101.56.50;
access_log yes;
location /static {
autoindex on;
alias /opt/soundshelter/static/;
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
# error_log /opt/soundshelter/soundshelter/soundshelter/nginx-error.log;
}
Running python manage.py collectstatic reports files were successfully copied but are still not being displayed.
Deployment handled by Fabric
from __future__ import with_statement
from fabric.api import *
from fabric.contrib.console import confirm
env.hosts = []
print "Here we go..."
def commit():
local("git add . && git commit")
def push():
local("git push origin master")
def prepare_deploy():
commit()
push()
def deploy():
code_dir = '/opt/soundshelter/soundshelter/'
with cd(code_dir):
run("git pull")
run("python manage.py collectstatic -v0 --noinput")
run("service nginx restart")
run("ps aux |grep gunicorn |xargs kill -HUP")
run("gunicorn -b PROD_IP soundshelter.wsgi:application")
commit()
push()
deploy()
First of all, it seems to me that your edited STATICFILES_DIRS points to the wrong folder, since you have /static/ folder, not /staticfiles/. Should be as it was originally:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Second, STATIC_ROOT should point to the static folder which will be served by webserver in pro (but preferably not in project folder). In your case:
STATIC_ROOT="/opt/soundshelter/soundshelter/soundshelter/static/"
I usually place static folder near the project one and use dynamic STATIC_ROOT instead of hardcoding:
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
#this will alow to collect your static files in /opt/soundshelter/soundshelter/staticfiles/static
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'staticfiles/static')
Now you should do collectstatic and it will collect all static files in the STATIC_ROOT directory.
In your Nginx Config did you try to set:
location /static {
instead of
location /static/ {
also make sure the user running nginx has read permissions to the static folder.
BAD SOLUTION - DO NOT USE IN PRODUCTION
https://docs.djangoproject.com/en/1.8/howto/static-files/
Adding this to urls.py did the trick
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Categories

Resources