Django/Apache address problem - django

I have a django app running on http://djangohost/appaddress. I'd like the project to be available at http://differentaddress/app . Currently I'm able to run app at the desired address but using {% url %} templatetags gives me improper address in the form http://differentaddress/app/appaddress. Also when I go to django app address directly all {% url %} links are in the form http://djangohost/app/appadress How can I change this ? I have these entrances in apache conf :
ProxyPass /app/ http://djangohost/appaddress/
ProxyPassReverse /app/ http://djangohost/appaddress/

You'll probably have to tell Django where it is running by manipulating SCRIPT_NAME
http://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#force-script-name
Or, if you want to keep things within Apache, you may give a try to mod_proxy_html - disclaimer: haven't used it myself, but it does claim to rewrite links in HTML pages

Maybe not a proper solution but still some workaround for the problem without interfering with apache's settings. Tested with mod_msgi and it works like a charm. Here's the link :
http://fromzerotocodehero.blogspot.com/2011/01/using-proxypass-with-django-project.html . Basically I've overriden built in url function here creating custom urlc temlpatetag. In tag's code I've added line replacing first occurence of unwanted app name with empty sign.

So you want to "mount" a Django site on a sub URL path? I already tried this with Apache and mod_proxy, and it was kind of a nightmare to find out. Here's what I have come up with (probably not complete or perfect):
# In your scenario
FORCE_SCRIPT_NAME = "/app/"
# End of settings
_prefix = (FORCE_SCRIPT_NAME or "")
LOGIN_URL = _prefix + LOGIN_URL
LOGIN_REDIRECT_URL = _prefix + LOGIN_REDIRECT_URL
LOGOUT_URL = _prefix + LOGOUT_URL
ADMIN_MEDIA_PREFIX = _prefix + ADMIN_MEDIA_PREFIX
Obviously, this prepends "/app/" to the most important hardcoded site URLs, plus it sets FORCE_SCRIPT_NAME to ensure that {% url something %} will result in an absolute URL of "/app/something", for instance.
This worked for me using mod_wsgi for the Django site and ProxyPass/ProxyPassReverse for the "mounting". Try it out and give me feedback, I'm interested whether this is a general solution.

Related

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/

Running Django site with a URL prefix

I'm trying to put my Django site in a subpath, say www.example.com/mysite/ but I can't get it to work 100%.
I read up on the answer Django Apache Redirect Problem , where it is suggested to just change the site in the admin from www.example.com to www.example.com/mysite/, which is exactly what I want to do and it almost works. All urls in the main urls.py gets redirected properly, but everything in the includes drop the "mysite" directive when using the links in the templates (one example is {% url journal_index %} which after the change should go to www.example.com/mysite/journal but goes go www.example.com/journal/).
Hope this makes sense.
Cheers!
Try adding the FORCE_SCRIPT_NAME setting:
FORCE_SCRIPT_NAME = '/mysite'

Django root site in virtual directory

The following is the setup:
I have a virtual directory in IIS 6 in which my Django app lives, IIS is configured to pass every request on that virtual directory to the Django WSGI handler
Let's say this is domain.com/virtual/
In my Django dev URL CONF I had urls configured like this: url( r'^home$, 'project.views.home' )
Question:
Is there an easy way (through Django settings OR server settings) to set some kind of ROOT_URL for the django app? (Without manually prepending as this is incompatbile with i18n_patterns)
Django should treat all patterns as rooted in the ROOT_URL and redirect - again - relative to that same ROOT URL.
Thank you in advance
I have done this in the past.
In your settings file add a setting called something like:
VIRTUAL_DIRECTORY = "your_virtual_directory/"
If you are doing dev or have this behind it's own site domain you can keep it blank.
Then in your site's urls.py file add this to all of your top level url patterns:
from django.conf import settings
urlpatterns = patterns('',
url(r'%sadmin' % settings.VIRTUAL_DIRECTORY),
)
Do the string pattern for all of your url patterns. You will only need to do this at the site level urls.py not for every app. This way if you have a non blank VIRTUAL_DIRECTORY then it will prefix it to all of your top level url patterns.

Getting Page not found (404) in Django 1.3.1 from bad url pattern

I am following along with this Django blog tutorial and can not get the url pattern given in the tutorial to work properly. The url.py code the author gives is
(r'^static/(?P
.*)$', 'django.views.static.serve',
{'document_root': 'c:/static/adornment'}),)
and I adapted it to my Linux set up like this
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('',
(r'^static/(.*)$', 'django.views.static.serve',
{'document_root': '/home/sez/blog/static/image.png'}
),
)
and after going to http://127.0.0.1:8000/static/image.png I received the following error
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/static/image.png
'image.png' could not be found
How can I make this work?
Change up your 'document_root' to be a directory, and make sure your STATIC_URL setting is set to /static/
The likely reason for the behavior you were experiencing is as follows. You probably have 'django.contrib.staticfiles' included in your INSTALLED_APS in the "settings.py" file. In that case, when you run "manage.py runserver" (and you have DEBUG = True in your "settings.py"), static files will be automatically served from your STATIC_URL by the staticfiles app and not by your 'django.views.static.serve' URL pattern. However, in your case staticfiles app is not set up correctly and won't find your 'image.png' file. You might want to read more about conventional serving of static files here: Managing static files.
For that matter, STATIC_URL is not supposed to be a filesystem path like you have now: STATIC_URL.
When you made it that way, you effectively disabled staticfiles app and your code started working as a result :)
So, to solve your problem "correctly", you need to either make sure that STATIC_URL and the URL path in your "urls.py" are different, for example, make one of them "/static/" and another one "/media/" (or something else), or just remove "django.contrib.staticfiles" from your INSTALLED_APPS altogether if you don't use it. (And, of course, the advice about making 'document_root' a directory was entirely correct. You can read more about using 'django.views.static.serve' here: Serving static files in development.)

Django redirects missing out WSGIScriptAlias part of url

I have a django application set up using mainly the admin interface with a few of my own views. Everything is working corrctly on the devlopment server on my local machine.
However on the production server, using Apache, and mod_wsgi, it is messing up the URLs when I issue a redirect statement in one of my views. Instead of going to
www.hostname.com/wsgi/django/admin/myapp/myform.html
it goes to
www.hostname.com/admin/myapp/myform.html
Apache doesn't recognise anything under an admin folder, so I get an error.
So in my apache configuration I have the following, so that anything under wsgi/django gets sent to my app:
WSGIScriptAlias /wsgi/django /project/production/public/wsgi/django_eclipse/myapp.wsgi
In my problematic view I have the following:
return redirect('/admin/sequencing/load_flowcell?' + params )
I can make this work, if I change the redirect to include the '/wsgi/django' part, but this means I can't keep the one on my development server the same. Is there a way in Django settings, or http.conf to set this so that my redirect automatically includes this part of the URL?
Django can use the sites framework to generate correct urls when reversing -- if you change the domain field in the Site row associated with your site (as indicated by SITE_ID in your settings.py) to http://www.hostname.com/wsgi/admin, then everything should work fine.
(There may also be a few places where you have plain urls, e.g. the LOGIN_URL or LOGIN_REDIRECT_URL settings that you should make sure include the /wsgi/admin part.)
Well, it's redirecting to exactly the URL that you told it to.
This is why you should never hard-code URLs anywhere in Django. If you used the URL-reversing functionality, it would automatically add the WSGI prefix - it knows about it already, and takes it into account when you use the {% url %} tag or the reverse() function.
Give the URL a name in your urls.py, and use that in the call to redirect rather than the URL, and all should work fine. No need for more settings.
EDIT: REAL FIX
from django.core.urlresolvers import reverse, get_script_prefix
....
#only of you absolutely HAVE to have a hardcoded url
return redirect(get_script_prefix()+'admin/sequencing/load_flowcell?'+params )
#better!
return redirect(reverse('admin:index')+sequencing/load_flowcell?'+params )
CAVEAT:
https://docs.djangoproject.com/en/dev/howto/deployment/modpython/#basic-configuration
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite <---- Make sure you have this
PythonDebug On
</Location>