Django root site in virtual directory - django

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.

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/

How do i configure django urls to make it so if it displays 404, it reroutes to Reactjs

The title is terrible - sorry about that.
So say I have a website say www.myhairynose.com/. I've configured my urls.py so that whenever the person enters www.myhairynose.com it redirects them to the index.html (where it displays the reactjs application). I've set reactjs with react-router and made it so when you click a button on the index page it goes to www.myhairynose.com/#/webpage.
Thing is... I don't want that.
I want it to go to www.myhairnose.com/webpage. I want react to handle this however and not django. ALL of this url thing should be in the same application of index.html. How do I configure django urls.py so that if I enter www.myhairynose.com/webpage it goes to the index of www.myhairnose.com ReactJs's application and then it checks to see if the route has webpage. Otherwise say if I went to www.myhairynose.com/asdkjaskldsaj (which the react route doesn't have) it should display a 404.
______TLDR______
Basically what I want to happen:
User goes to website.com/name
>if website.com/name exists in django - it returns a html doc
>if not then it redirects to website.com/ where ReactJs will handle the url and see if it matches any of the routers
...> if it does, then it displays that route
...> if not then it displays a django 404 or a custom 404 page.
How do I configure django and reactjs to do this?
Are you using Django to render react? I am making the assumption that you have some view like views.LoadReactView.
What you need is a catch all route.
from django.contrib import admin
from myapp import views
urlpatterns = [
...
url(r'^admin', admin.site.urls),
url(r'^', views.LoadReactView.as_view()),
]
This should appear as your very last pattern. You essentially are saying "after checking all the other routes, if there are no matches, go here".
In addition, you could also actually just define your main view as your 404 handler
urlpatterns = [
...
]
handler404 = views.LoadReactView.as_view

Redirecting old PHP links to Django urls

I am getting a lot of search engine referral links for my previous PHP developed site that has now been migrated over to Django. I made a url redirect for the old php links like search.php?name=john+smith to the same view for my django search url as shown here:
urls.py
url(r'^search.php/$', profile_search, name='search'),
url(r'^search/$', profile_search, name='search'),
Will Google eventually update those old links if I redirect through urls.py or do I need to make a 301 redirect? If so how would I do this with django and nginx?
I would do this at nginx level - this is much more efficient than having Django handle it. Assuming the Django view expects the same query arguments, you can do this in your nginx server block:
location = /search.php {
return 301 http://$server_name/search/$is_args$args;
}
This will redirect all requests for search.php to /search/, preserving any query arguments.
A 301 response is definitely the correct approach - you don't want to serve duplicate content on different URLs.
Unless you have HttpResponseRedirect in your profile_search method, you don't actually have any sort of redirect here at. But what you really want to use is HttpResponsePermanentRedirect
def profile_search(request):
return HttpResponsePermanentRedirect('/somether/url/?based_on_request_params')

redirect rule for nginx?

I am running my django app using nginx. I want to write a redirect rule such that
if user hit the url http://example.com/django/nginx/ then it redirect it to
http://example.com/django/#!/nginx/. I want o know the regex for it.
Thanks
You'll want to handle this on the client side (through Javascript, most likely), not through nginx.
From what I understand, the point of # in URLs (as per the spec) is that the portion that comes after # doesn't reach the server.
Also, see this question for some info on JS libraries for working with hash-bang urls: Are there any javascript libraries for working with hashbang/shebang (#!) urls?
Given you example I'm assuming that you are working with URLs in the form "http://1/2/3/" only, so nothing going beyond 3. Where you want to separate 2 and 3 with "/#!/". If that is the case you can try the following.
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
('^django/(?P<ajax_section>\w+)/$', redirect_to, {'url': '/django/#!/%(ajax_section)s/'}),
)
The above assumes that 2("django") in the URL will be fixed. If that is not the case you will have to try and make it a parameter as well.

Unable to make a domain redirection in Django from example.com to www.example.com

I get the following message when I browse to example.com
500 - Internal Server Error
I get my 404 error message when I browse to www.example.com which indicates my site is alive.
How can you make a domain redirection without .htaccess by Django from example.com to www.example.com?
My urls.py
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
(r'^home/', include('index.html')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/(.*)', admin.site.root),
)
[edit]
I have the following answer from Djangohosting:
Remove the website proxy for [example.com] and add [example.com] in the aliases section of the [www.example.com] website.
I am not completely sure what it means.
How can you remove the website proxy for example.com?
Where can you find the aliases section of the website www.example.com?
I don't know if it solves all your problems but if you want to do it via django, try a middleware
from django.http import HttpResponseRedirect
class WWWRedirectMiddleware(object):
def process_request(self, request):
if not request.META['HTTP_HOST'].startswith('www.'):
return HttpResponseRedirect('http://www.example.com')
Remember that it must be executed before any other middleware.
Based on this one, didn't test it.
Checking out PREPEND_WWW setting might help.
The 500 Internal Server error is likely caused by this line:
(r'^home/', include('index.html')),
The include() function is a way to include other URL config files, not static HTML files. You'd have to either serve index.html as a static file at the given URL (/home), or write a view that simply renders the file.
I get the following message when I browse to example.com
500 - Internal Server Error
I get my 404 error message when I browse to www.example.com which indicates my site is alive.
It is likely the other way around. The 500 message means that your site is active, but giving an error. What you have to understand is that the example.com/www.example.com part of the url serves to find which server to connect to. By the time your Django application gets called, this part has already been completed, so there os no way to do this from Django.
Instead, you want to set up www as a subdomain of example.com and make them point the same place. See the first example here: virtualhosts examples
UPDATE I just noticed that you stated that your 404 was showing up, so ignore the first two sentences. Either way, the solution would likely be the same. :-)