I've been struggling with this for a couple of days - so I'm sticking them here for memoryade. I'm building a site from Django, using Nginx as the front end.
Maybe I'm suffering from Apache hangovers, but I've been having problems getting a nice solution to URLs mapped to views based off the same template. I think things were confused by also wanting to map the root of the site to a Django URL of '/'. Probably bad form, but I basically used my 'index.html' as a template, with Django style {%...%} blocks to be overridden by templates for each section. This means I have a Django project with no apps defined at the beginning, save for admin - which has it's own media mapping in Nginx.
The problem was that I managed to configure Nginx to map to '/' - and I could get Django to respond with different views in the root app - things like 'index' and 'projects' - but I would loose all the media. They would always append their part of the URL when looking for media like images and style-sheets. So if I went to 'projects' all links to 'media/image.png' would end up as 'projects/media/image.png' - I think Django expects all apps to contain their own media directory. So partly through thinking that I was messing with things having defined views in the default Django app, and mapped it to '/' - spent 2 days trying all sorts of Nginx and 'urls.py' configurations.
The answer was stupid - edit the original template to use links mapped to '/' so instead of "media/image.png" put "/media/image.png" - relative to the root, rather than the section your in.
urls.py
urlpatterns = patterns('',
('^$', index),
('^projects/$', projects),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
views.py
def index(request):
return render_to_response('home.html', {'content': "HELLO THERE!"})
def projects(request):
return render_to_response('home.html', {'content': "Projects"})
I'm using home.html twice, just adjusting the content with different views. 'home.html' looks like this
{% extends "index.html" %}
{%block content%} {{content}} {%endblock%}
Then the Nginx configuration just looks like this:
server {
#listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /home/me/Projects/mysite;
#index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
location /media {
alias /home/me/Projects/mysite/media ;
}
location /admin/media {
alias /home/me/Projects/mysite/mysite/admin/media;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.html
#try_files $uri $uri/ /index.html;
fastcgi_pass 127.0.0.1:8000;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SERVER_PORT 80;
fastcgi_param SERVER_PROTOCOL wsgi;
}
}
I added the last three myself - I hadn't seen them used anywhere - but it stopped my logs being full of error about them missing....
This approach works perfectly, and can be moved around, chopped up onto different servers etc...