django : Serving static files through nginx - django

I'm using apache+mod_wsgi for django.
And all css/js/images are served through nginx.
For some odd reason, when others/friends/colleagues try accessing the site, jquery/css is not getting loaded for them, hence the page looks jumbled up.
My html files use code like this -
<link rel="stylesheet" type="text/css" href="http://x.x.x.x:8000/css/custom.css"/>
<script type="text/javascript" src="http://1x.x.x.x:8000/js/custom.js"></script>
My nginx configuration in sites-available is like this -
server {
listen 8000;
server_name localhost;
access_log /var/log/nginx/aa8000.access.log;
error_log /var/log/nginx/aa8000.error.log;
location / {
index index.html index.htm;
}
location /static/ {
autoindex on;
root /opt/aa/webroot/;
}
}
There is a directory /opt/aa/webroot/static/ which have corresponding css & js directories.
The odd thing is that the pages show fine when I access them.
I have cleared my cache/etc, but the page loads fine for me, from various browsers.
Also, I don't see 404 any error in the nginx log files.
Any pointers would be great.

I think using root in location block is incorrect. I use alias and it works fine, even without re-configuring django.
# django settings.py
MEDIA_URL = '/static/'
# nginx server config
server {
...
location /static {
autoindex on;
alias /opt/aa/webroot/;
}
}
Hope this makes things simpler.

server_name must match hostname in link/script URLs. Either declare your configuration as default for this interface:port pair (listen 8000 default)
Nginx must listen on the interface where your host's IP is bound (seems ok in your case)

I also struggled with this. However, following trick worked for me:
server {
listen 8000;
server_name localhost;
access_log /var/log/nginx/aa8000.access.log;
error_log /var/log/nginx/aa8000.error.log;
location / {
index index.html index.htm;
}
location ^/static/ {
autoindex on;
root /opt/aa/webroot/;
}
}
I just marked static as a regex with ^ and nginx started serving static files. No modification on Django side was needed.

MEDIA_URL shall not be used to serve the Static content like js etc. Django provides a separate STATIC_URL settings option that can be used.
So this can be changed as
<script type="text/javascript" src="{{STATIC_URL}}js/jquery-1.3.2.min.js"></script>
Also, its more standard to use staticfile app templatetag like this:
{% load static from staticfiles %}
<script type="text/javascript" src="{% static 'js/jquery-1.3.2.min.js' %}"></script>
Docs Here

Fim & Alexander - Thanks for the hints those helped.
Here is how I solved it for anyone stuck in the same boat -
settings.py -
>MEDIA_ROOT = ''
MEDIA_URL = 'http://x.x.x.x:8000/static/'
In my html -
<script type="text/javascript" src="{{MEDIA_URL}}js/jquery-1.3.2.min.js"></script>
In my views.py -
return render_to_response('templates/login-register.html', {},
context_instance=RequestContext(request));
nginx inside the sites-available config file -
listen x.x.x.x:8000;
server_name x.x.x.x.;
Restarted nginx
Restarted apache

Related

NGINX throws 404 and wont load static

Hopefully, Y'all can help me with this one and hopefully I am in the right areas to post this. Just recently began learning Django and I am trying to get it deployed to Linux. I have been using gunicorn and nginx for this deployment and for the most part I have been successful. I am able to successfully deploy and interact with my app, navigate pages and interact with some of the post requests. The only thing I have been banging my head around trying to figure out what is going on with my static files. All of my css and images do not display currently and I have tried searching everywhere for the resolution. I have tried using an alias in the nginx file and I have made sure that my static root and URL is fine, nothing i have tried has done the trick. the weird this is, when looking at the access logs from nginx it shows the Get request going to the correct file and path, but shows 404? I am at a loss here lol! What is really weird is that the static folder contains a few csv's that are processed and served by a view those work correctly so I am confident that the url and root in setting.py is correct. Some of the other things I have tried include setting STATIC_URL to '/' and '/Static_File_Storage' neither worked one gave me an error about media url and the other gave me a permission denied error. This is also for a network-only site and won't be accessed by anyone other than a few employees so I am not worried about having it pulling from home.
**NGINX FILE:**
server {
listen 80;
server_name redacted;
location = /favicon.ico { access_log off; log_not_found off; }
location /Static_File_Storage/ {
alias /home/beachhouse/PycharProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}}
**setting.py**
STATIC_ROOT = os.path.join(BASE_DIR, "/Static_File_Storage/")
STATIC_URL = 'home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/'
**Actual Location of File:** /home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/css/style.css
**output on logs: "GET** /home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO_Static_File_Storage/css/style.css HTTP/1.1" 404 1226
**Static Tags in HTML:** {% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"/>
<img class="login_img" src="{% static '/logo.png' %}" alt="logo">
View call for static: df = pandas.read_csv(static('Flash_Changes.csv'))
Change STATIC_URL to "/Static_File_Storage/".

Django : Page Not Found when trying to access static files

I know there are already several threads on the topic. I've been through most of them (especially all the troubleshooting listed in this one) but I can't figure out my issue.
I am trying to use a Bootstrap template in my Django project, and I'd like to simply start by accessing the files in the /static/ directory. My project directory looks like this :
Whenever I try to load the page http://localhost:8000/static/theme/assets/css/style.css it returns a Page not found error (and obviously no CSS/JS content appears on my index).
Here are my settings:
I have debug = True
ÌNSTALLED_APPS contains django.contrib.staticfiles
settings.py looks like this :
STATIC_URL = "/static/"
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static/"),)
But I still can't access anything from the /static/ directory.
I tried to access the CSS and JS files in base.html this way :
{% load static %}
...
<link href="{% static 'theme/assets/css/style.css' %}" rel="stylesheet">
I really have no clue how I could solve this.
Thanks in advance for your help !
Is base.html properly bound to a URL and to a view function via a URL dispatcher ? Can you access that file from your browser ?
If yes, try to substitute this line
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static/"),)
with this one
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)

Adding domain path to django html templates

I am serving a django app with a combination of nginx reverse proxy and waitress. In the nginx configuration the app is linked via a location:
location /app/ {
proxy_pass http://localhost:8686/;
}
While the app runs on via waitress on port 8686.
Now, if I go to the domain.com/app, I the index page is served correctly. Though, my django html template contains the following link:
<p> You are not logged in.</p> <button>Login</button>
When I press that button I get to
domain.com/accounts/login
but it should be
domain.com/app/accounts/login
I wonder how to change the code so that it works independently of where the app is linked.
In urls.py the urls are included like this:
urlpatterns: = [...,
path('accounts/', include('django.contrib.auth.urls'))]
Define the url in urls.py (most probably you've already done this) and then use reverse in templates:
<button>Login</button>
Then rewrite URLs in nginx to make your app think that you're accessing /accounts/login instead of /app/accounts/login:
location /app/ {
rewrite ^/app(.*)$ $1 last;
proxy_pass http://localhost:8686/;
}
Docs:
https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#std:templatetag-url
https://www.nginx.com/blog/creating-nginx-rewrite-rules/

Django csrf verification fails after switching off https

I am using Django 1.7.1 , I made a single change outside of my django web app , i.e switched off https inside nginx since my django webapp moved within the company firewall.
I made no other changes to the webapp , like in any of the django code: I am testing the webapp access via the company vpn.
The home page , which is a form loads fine when I go to http://mywebapp.mycompany.com.
Now , When I hit submit. I see the CSRF verification failure with a reference to https://mywebapp.mycompany.com! as detailed below. I even get the error in incognito mode to rule out any old cache issues.
I wanted to know the source of the error and feel it is outside of my webapp and within some vpn configuration/ browser cache / some other cache.
I have checked the possible reasons for CSRF failure given in the django message , and am not doing any of those "bad" things.
Any ideas on how to troubleshoot this. I want to know whether this is a VPN config problem , an nginx config problem or a django "best practices" problem.
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
Referer checking failed - http://mywebapp.mycompany.com/ does not match https://mywebapp.mycompany.com/.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
I am not doing any of these. My form uses :
<form role="form" action={% url "sequence_input" %} data-persist="garlic" data-destroy="false" method="post" enctype="multipart/form-data">{% csrf_token %}
The calls to the form are using RequestContext:
return render(request,'sequence_input_form.html',{'form':form})
And I have the following context processors:
TEMPLATE_CONTEXT_PROCESSORS= ("django.core.context_processors.static",
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",)
My Nginx conf indicating commented lines.
server {
listen 80;
listen [::]:80 ipv6only=on;
#listen 443 default ssl;
charset utf-8;
# Make site accessible from http://localhost/
server_name [my server ip];
#if ($ssl_protocol = "") {
# rewrite ^(.*) https://$server_name$1 permanent;
#}
#if ( $scheme = "http" ) {
#return 301 https://$server_name$request_uri;
#}
#ssl_certificate /home/mywebapp/mywebapp/mywebapp_cert.crt;
#ssl_certificate_key /home/mywebapp/mywebapp/mywebapp_key.key;
#ssl_certificate_key /home/mywebapp/mywebapp/harijay/mywebapp_webhop_org.key;
location / {
uwsgi_pass django;
include /home/mywebapp/mywebapp/uwsgi_params;
uwsgi_read_timeout 60000;
root /home/mywebapp/mywebapp;
#index pam_lister/templates/sequence_input_form.html;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
location /static {
autoindex on;
alias /home/mywebapp/mywebapp/static/;
}
}

Django: path to static file is wrong in generated HTML

I have some javascript that I would like to run on a particular page of a Django site I am building. In the template I currently have:
<script type='text/javascript' src='{% static "/home_page/github_repos.js" %}'></script>
The HTML that is generated by this is:
http://localhost:8000/home_page/github_repos.js
The problem is that I have the javascript in /static/home_page/.
If I hardcode in the path as:
<script type='text/javascript' src='static/home_page/github_repos.js'></script>
Everything works fine.
However, I am getting odd behavior that I do not understand:
If, in the template I set the path like this:
<script type='text/javascript' src='{% static "static/home_page/github_repos.js" %}'></script>
The HTML generate has a src attribute of /static/static/home_page/github_repos.js
The part that is really throwing me off is that if I do not put /static/ at the front of the src when using the template tags (like the first example I give), /static/ is not added, however, if I do add /static/ at the front, it gets added. I need /static/ added to the front of the src attribute, but only once.
Some relevant information:
My home_page app resolves to '/' as the url, so localhost:8000/ gets you to the home page.
I have included'django.contrib.staticfiles' in my installed apps
Finally, STATIC_URL = '/static/'
Is this problem occurring because my home_page app resolves to the root address of localhost:8000/?
Any help is appreciated.
This issue is because the path in the static tag should be relative to the static directory. From the docs:
Uses the configured STATICFILES_STORAGE storage to create the full URL for the given relative path
You're using an absolute path. Instead, you should use:
{% static "home_page/github_repos.js" %}
Note the omission of the leading forward slash.