{% url admin:index %} generating wrong urls - django

My django site is served up with the following in Apache's config:
WSGIScriptAlias /studio /django/studio/bin/django.wsgi
My urls.py looks like:
urlpatterns += patterns(
'django.contrib',
(r'^admin/', include(admin.site.urls)),
(r'^accounts/login/$', 'auth.views.login'),
(r'^accounts/logout/$', 'auth.views.logout'),
)
...and yet:
[admin]
...generates a link to /admin rather than /studio/admin.
Bizarrely, the urls within the admin interface itself are fine.
I'm using:
Python 2.5.2-3
Django 1.1.1
mod_wsgi 2.5-1~lenny1
apache2 2.2.9-10+lenny6
Can anyone tell me what I'm doing wrong?
cheers,
Chris

This is a bug in Django, see:
http://code.djangoproject.com/ticket/12464
The problem is that because Apache's rewrite engine is on as a result of rewriting I need to do elsewhere in the virtual host, the SCRIPT_URL environment variable is set. But, when a request is made to /project through Apache, PATH_INFO is empty, which results in SCRIPT_NAME being incorrectly set as an empty string.
Until this bug is fixed, inserting the following RewriteRule into the Apache configuration will safely work around the problem by ensuring that PATH_INFO is never empty.
RewriteEngine On
RewriteRule ^/project$ /project/ [R]
WSGIScriptAlias /project /django/project/bin/django.wsgi

Your Django instance knows nothing about the /studio part of the URL as it is handled in WSGI. You have to manually prepend it either in templates or, better, in urls.py:
in settings.py:
BASE_URL = '/studio'
in urls.py:
r('^%s/admin/' % settings.BASE_URL, include(admin.site.urls)), ...
Then your url reversing will work as expected. You admin links work because once you are in the admin interface all links are relative.

Related

Django redirect loop in form submit

Just to clarify, this is the first time I'm putting a django website to production.
I have a simple website in django that works locally. But when I deploy it in the production server it enters in redirect loop when I submit a form. Then the browser just tells me that a redirect loop occurred and asks to empty the cache and so on...
This problem happens in the admin. I don't know if it would happen in the frontend because it just doesn't have any form in the frontend.
Notes:
I don't have any funky middlewares.
I tested in a virtual machine with more or less the same specs of
the production server and it works fine.
The submitted data is correctly handled and saved
The rest of the website is fine
I'm using apache with wsgi in a shared host, through a .htaccess.
At this point I don't rule out the chance of a dns misconfiguration, but I already checked and looks fine.
.htaccess:
AddHandler wsgi-script .wsgi
DirectoryIndex app22.wsgi
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app22.wsgi/$1 [QSA,PT,L]
</IfModule>
app22.wsgi:
import os, sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'BTT.settings'
path = '/home/bttmonch/apps'
if path not in sys.path:
sys.path.append(path)
path = '/home/bttmonch/apps/ENV/lib/python2.7/site-packages'
if path not in sys.path:
sys.path.append(path)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
At this point I created a fresh new app with just the admin activated, to see if it was some codding issue and put it on the server. And the same thing happens.
I am using the same .htaccess and .wsgi files that I mentioned before.
My urls.py is just the basic:
from django.conf.urls.defaults import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
I am accessing the app via test.domainname.com.
I already tried accessing it through test.domainname.com, test.domainname.com/app22.wsgi, domainname.com/test/ and domainname.com/test/app22.wsgi...
After poking around in the server I stopped getting a redirect loop. But now every time I save a form I get a 403 error. Than I clear the browser cookies and all comes back to normal, and the form data is successfully saved in the database.
At this point a just don't now what else to try...

RedirectMatch 301 in urls.py for Django

Since Django does not do .htaccess (at least on my host), I need to do a 301 RedirectMatch in the similar manner that you'd do an .htaccess RedirectMatch:
RedirectMatch 301 ^/oldfolder/(.*)$ http://sub.domain.com/newfolder/$1
The wildcard does not work in the same manner that it does for the .htaccess, so any help appreciated! It must be a permanent redirect too so that search indexes will know it got moved. What am I redirecting is images to my new CDN subdomain.
Not tested:
# Django >= 1.3
from Django.views.generic.base import RedirectView
urls = patterns('',
# some patterns here...
url(
r"^oldfolder/(?P<whatever>.*)$",
RedirectView.as_view(
url="http://sub.domain.com/newfolder/%(whatever)s",
)
),
# more patterns here
)
[edit] Re-reading your question: "What am I redirecting is images to my new CDN subdomain" - if that's about static medias (images, css etc) then they shouldn't be served by Django but by your front web server (Apache, Nginx, whatever) so assuming Apache you can use a simple RedirectMatch in your vhost config.

Django is redirecting from HTTPS to HTTP

I have a Django ecommerce site running, and have purchases and installed an SSL cert for it.
I have added a VirtualHost entry:
<VirtualHost *:443>
#Basic setup
ServerAdmin blah#test.com
ServerName test.com
ServerAlias www.test.com
Alias /media/admin/ /home/test/public_html/test/release/env/lib/python2.6/dist-packages/django/contrib/admin/media/
Alias /static/ /home/test/public_html/test/release/static/
Alias /media/ /home/test/public_html/test/release/media/
<Directory /home/test/public_html/test/release/>
Order deny,allow
Allow from all
</Directory>
RewriteEngine On
LogLevel warn
ErrorLog /home/test/public_html/test/logs/error.log
CustomLog /home/test/public_html/test/logs/access.log combined
WSGIDaemonProcess test user=www-data group=www-data threads=20 processes=2
WSGIProcessGroup test_ssl
WSGIScriptAlias / /home/test/public_html/test/release/apache/test.wsgi
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/test.com.crt
SSLCertificateChainFile /etc/apache2/ssl/gs_root.pem
SSLCertificateKeyFile /etc/apache2/ssl/www.test.com.key
</VirtualHost>
Here is the urls.py file:
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
from django.conf import settings
from gallery.models import LOCATIONS, Photo
admin.autodiscover()
from satchmo_store.urls import urlpatterns as satchmo_urls
from satchmo_store.shop.views.sitemaps import sitemaps
from cms.sitemaps import CMSSitemap
sitemaps['pages'] = CMSSitemap
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^search/', include('haystack.urls')),
# Include satchmo urls. Unfortunately, this also includes it's own
# /admin/ and everything else.
url(r'^shop/', include(satchmo_urls)),
url(r'^sitemap\.xml/?$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
url(r'events/gallery/(.*)/(.*)/$', 'gallery.views.events_image'),
url(r'locations/view-all/(.*)/$', 'gallery.views.locations_image'),
url(r'locations/view-all/$', 'gallery.views.locations_view_all',{
'queryset':Photo.objects.filter(gallery__category=LOCATIONS).distinct()}),
url(r'^contact-us/', include('contact_form.urls')),
url(r'^', include('cms.urls')),
)
if settings.DEBUG:
urlpatterns = patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
(r'^404/$', 'django.views.defaults.page_not_found'),
(r'^500/$', 'django.views.defaults.server_error'),
) + urlpatterns
There is also a conf for non ssl which is working fine.
Whenever I request the HTTPS version of the site, I get a 302 header response which redirects to the HTTP version.
There are no redirects in the apache conf that explicitly state go to port 80.
Ive been banging my head against this for a while, any help would be great!
Thanks
You probably already fixed it and it could be an entirely different problem, but I just came across something that sounds somewhat similar and as I did not find an answer that addressed your issue, I thought it might be worth to post a reply (despite I was having a 301 and you a 302).
I am running a Django site (Django 1.6.1) with gunicorn behind nginx. So nginx does the SSL. The environment variable HTTPS is set to on.
When I set up a test server without an http-to-https redirect, I noticed that some requests end up being redirected to an http address - similar to what you describe, but in my case it was just for one particular link. After looking into the request and response headers, I found out:
The initial request https://example.org/test got redirected by Django/gunicorn with 301 MOVED PERMANENTLY to http://exmaple.org/test/. nginx then responded with 400 Bad Request - The plain HTTP request was sent to HTTPS port.
Quickly I came across a setting I had not paid much attention to before: APPEND_SLASH (https://docs.djangoproject.com/en/1.6/ref/settings/#std:setting-APPEND_SLASH) with the default value True.
After adding APPEND_SLASH = False to my settings.py file, a request to https://example.org/test resulted in a 404 NOT FOUND response, without a redirect to http. So it seems that APPEND_SLASH does not respect the HTTP environment variable setting - I guess configuring SECURE_PROXY_SSL_HEADER (https://docs.djangoproject.com/en/1.6/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER) would solve this, I have not tested it yet.
By the way, the reason for that "faulty" link in my case was a hard-coded link in a template. The easy way to avoid links like that is using the built-in {% url ... %} template tag (https://docs.djangoproject.com/en/1.6/ref/templates/builtins/#url [sorry, I could not make this link clickable because I don't have "at least 10 reputation"...]).
Perhaps this helps you or anyone else who wonders why Django sometimes redirects from https to http.
I know this is an old question but I have just spent hours searching for a solution to an identical problem so I thought I would post what I eventually worked out here.
I was using Satchmo as the original poster was, It has a middleware class satchmo_store.shop.SSLMiddleware.SSLRedirect which by default sends a redirect exactly as described in the original question from https to http with a 302 header response. Commenting the line in MIDDLEWARE_CLASSES fixes the problem and may be OK if anyone wants to run completely over https but the documentation http://satchmo.readthedocs.org/en/latest/configuration.html#ssl explains how to use it properly which is what I am going to try to do.
Only thing that I can think of is your site setting in the database. If you put an explicit port number in your Site object... Could you take a look in your admin?

Django set up with WSGI in directory below the domain root: Url problems in templates

Django has been up and running on my mod_wsgi implementation of Apache (on Windows 7 x64, btw) for a bit. This was a huge pain, complete with having to actually hand-modify registry values to get things to install correctly and to get Django to use the same MySQL install as all my other apps. I also had to modify the PATH variable by double-escaping parentheses (Program Files (x86)) because they were screwing with batch files. But this is mostly Microsoft's fault and I'm rambling.
Here is my issue:
All of the URLs used in the URLCONF and in views work correctly. The only thing which doesn't is in templates when I try to work off the site root URL. I am running a development server and I have two Django sites, this particular one running off of www.example.com/testing.
In the templates, if I just put "/" in an < a >, then it will point to www.example.com/, and NOT www.example.com/testing/. I have read a topic on this but the issue wasn't resolved because the poster was being stubborn. I am posting my WSGI configuration in the httpd.conf below:
Listen 127.0.0.1:8001
VirtualHost *:8001 >
ServerName ****.net/testing
ServerAdmin *******#gmail.com
ErrorLog ********.log
WSGIScriptAlias /testing ****/htdocs/testing/apache/django.wsgi
Directory ****/htdocs/testing/apache >
Order deny,allow
Allow from all
/Directory>
Location "/media">
SetHandler None
/Location>
/VirtualHost>
Note: all "<" omitted so the tags would show
Here is the file django.wsgi in the above directory:
import sys
import os
sys.path.insert(0, '*****/Django/')
sys.path.insert(0, '*****/htdocs/')
sys.path.insert(0, '*****/htdocs/testing')
sys.path.insert(0, '*****/htdocs/testing/apache')
os.environ['DJANGO_SETTINGS_MODULE'] = 'testing.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
import testing.monitor
testing.monitor.start(interval=1.0)
I have an Nginx frontend which passes any non-static file from testing/ to :8001 for Apache to catch with this virtualhost.
If I omit the root "htdocs/" line from the django.wsgi file, I just get 500 errors on the site. Also, if I use the URL form relative to the current URL (ie "example/" instead of "/example/"), that works alright. But if I add the initial "/" to put the URL off the root, it will make it off of "www.example.com" instead of "www.example.com/testing" like I wanted.
Sorry for the very long post, but I wanted to be as clear as possible. Thank you for your time.
This is why you should not hard-code URLs in your templates. Of course / will take you to the root of the site, not the root of your app - that's what it's supposed to do.
Instead, give your root view a name in your urlconf:
urlpatterns = patterns('',
url('^$', 'myapp.views.index', name='home')
)
now in your template you can do:
Home
and this will correctly resolve to /testing/.

django urlconf or .htaccess trouble

I am running my django project from subfolder of a website. Lets say the address where my project is meant to open from is.
http://example.com/myproject/
the myproject folder is root folder for my user account. In that folder i have fcgi script that starts my project. The .htaccess file in the folder contains this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
The trouble is, that at some cases, instead of redireting user to page like
http://example.com/myproject/social/someurl/
it redirects to
http://example.com/social/someurl/
which does not work. What i want to know is how to fix this problem.
Redirects in django-socialauth (github.com/uswaretech/Django-Socialauth), socialauth.views.py line 177 redirects without /myproject/, similar to the generic example above. I also use django cms2.0 in the project and it redirects user at admin auth to example.com/en/myproject/admin/, not example.com/myproject/en/admin. But that could be django cms's problem.
Is this kind of behaviour django problem and i should change it with urconf and add myproject to all urls, or should i do this with .htaccess? I found similar question, which, sadly, remains unanswered:
How to write .htaccess if django project is in subfolder and subdomain?
Alan.
It's seems that django-cms-2.0 add the locale prefix to the url using the middleware level. Very well indeed.
But what's more interesting is that they prefix all of the url using resolve('pages-root')
So, you might be able to do this in the urls.py instead...
if not settings.DEBUG:
urlpatterns += patterns('',
url(r'^myproject/$', details, {'slug':''}, name='pages-root')
)
Just make sure that you append the above urlpatterns before the cms.urls.
What if you try
RewriteRule ^(myproject/.*)$ mysite.fcgi/$1 [QSA,L]
Set the RewriteBase:
RewriteEngine On
RewriteBase /myproject/
In /urls_production.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^myproject/', include('urls')),
)
In /settings_production.py
from settings import *
ROOT_URLCONF = 'urls_production'
Make sure you set DJANGO_SETTINGS_MODULE to settings_production in the server environment.