I have a django server and an angular app.
I am able to launch the angular app and navigate to the various parts of the site using links i have added to the app.
But if I want to go to a part of the site directly I get a 404 error.
example if I have a link in my app that directs me to
niftysite.com/team
it works
but if I put in my browsers url
niftysite.com/team
it fails with 404
I understand this is because the default behavior is to look for the link to the page in the servers urls.
I also understand that the fix is to have server side 404s redirect to the angular index.html page with the route params included.
My question is how?
I have already started on an implementation but I am not sure how to fix it. Any guidance the rest of the way through would be helpful.
here is what I have so far.
urls.py
handler404 = views.error_404
views.py
from django.shortcuts import render
def error_404(request):
data = {}
return render(request, 'index.html', data)
similar to this question, but I am not using Nginx
How to redirect 404 requests to homepage in Django single page app using Nginx?
Here is the implementation:
urls.py
url(r'^.*$', views.PassToAngular.as_view())
make sure this url is the last url in your urls array.
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
class PassToAngular(TemplateView):
def get(self, request, **kwargs):
return render(request, 'index.html', context= None)
thanks to MihirKavatkar for your help!
Related
I need to serve a particular static asset only to users logged into my Django site. I'm serving static assets through Apache. For various reasons I’m not interested in standing up a full CMS — I just need to make sure non-qualified site visitors cannot download this particular file.
This is really low traffic site so failing all else I can hardcode a urlpattern & serve it as a template.
But there's gotta be a smarter way to do this, right?
EDIT:
Here’s where I settled for now:
# views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
#login_required
def secretfile(request):
return render(request, 'secretfile.xls')
# urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'secretfile.xls', views.secretfile),
]
I'm going through the Django tutorial and am on part 5: Testing. I run into the problem where I'm using the DetailView and ListView "shortcut" views to factor out code (as suggested by the tutorial), but when a 404 page is displayed, a 200 status code is returned instead. Am I doing something wrong? The tutorial says the status code should be 404.
Thanks!
You need to define the Http header to have a 404 status.
return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)
It is important to inform the search engines that the current page is a 404. Spammers sometimes creates lots of urls that could seem that would lead you to some place, but then serves you another content. They frequently make lots of different addresses serve you almost the exact same content. And because it is not user friendly, most SEO guide lines penalize that. So if you have lots of addresses showing the same pseudo-404 content, it could not look good to the crawling systems from the search websites. Because of that you want to make sure that the page you are serving as a custom 404 has a 404 status.
If you are trying to make a custom 404 page, here it is a good way to go:
Into your application's urls.py add:
# Imports
from django.conf.urls.static import static
from django.conf.urls import handler404
from django.conf.urls import patterns, include, url
from yourapplication import views
##
# Handles the URLS calls
urlpatterns = patterns('',
# url(r'^$', include('app.homepage.urls')),
)
handler404 = views.error404
Into your application's views.py add:
# Imports
from django.shortcuts import render
from django.http import HttpResponse
from django.template import Context, loader
##
# Handle 404 Errors
# #param request WSGIRequest list with all HTTP Request
def error404(request):
# 1. Load models for this view
#from idgsupply.models import My404Method
# 2. Generate Content for this view
template = loader.get_template('404.htm')
context = Context({
'message': 'All: %s' % request,
})
# 3. Return Template for this view + Data
return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)
The secret is in the last line: status=404
Hope it helped!
I look forward to see the community inputs to this approach. =)
You can
return HttpResponseNotFound(render_to_string('404.html'))
instead.
Implementing page not found in django and have looked at the documentation 404
I do not get a page not found error as yet what ami doing here
In my code in urls i have done the following,
url(r'^$', 'site_config.views.pagenotfound')
from django.http import Http404
def pagenotfound(request):
return render_to_response('polls/pagenotfound.html', {})
The way you handle 404 and 500 in django is: by default, in the templates directory, create a 404.html
If you need a custom handler, just add these to urls.py
handler404 = 'views.page_not_found_custom'
handler500 = 'views.page_error_found_custom'
design the 404.html page the way you want
Is there a way to render a html page without having a view model in django if a page is going to display only static html?
Also, can I redirect to a html page instead of a url? For example, instead of doing this:
return HttpResponseRedirect('form/success/')
can I do this:
return HttpResponseRedirect('success.html')
?
direct_to_template no longer works in Django 1.8. Here is how to do it in 1.8, in the urls.py:
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name="your_static.html"), name='whatever'),
]
You can render a template without a view using the generic view direct_to_template.
Redirecting to success.html isn't the way to go in django since success.html doesn't have an associated URL. You always have to bind the template to an url via a view (direct_to_template is a view which gets all its arguments from the conf in urls.py, but it's still a view)
For static HTML you could use Flatpages app.
You could also serve rendered templates (which could contain only static HTML) but you will need a view:
from django.shortcuts import render_to_response
def some_view(request):
return render_to_response('sometemplate.html')
About redirection, basically you can't redirect to HTML page by just giving the filename, even if it were statically served by the web server you would still be using a URL that points to that file.
I'm pretty sure this isn't what OP wanted to do, but if someone wants to render something without a view, (for sending an email or appending to other html code), you can use this:
from django.template.loader import render_to_string
html = render_to_string('template.html', params)
Use lambda function.
urlpatterns = [
path('', lambda request: render(request, 'homepage.html'))
]
I'm starting a new web app project using Django and Pinax. I want to be able to give my users unique domain names like Wordpress and other sites do : username.wordpress.com. I'm not sure how to approach this with Django, since the url parsing logic (in urls.py) starts with the url AFTER the domain name.
More specifically, there will be multiple groups of users, each group having a unique name. Not sure that makes a difference, but I thought I should mention that.
Is there some way I can manipulate the http request so that the URL looks to Django as if the url were something like www.domain.com/groupname, but still showed in the browser address bar as groupname.domain.com?
You can use some custom middleware to intercept the request and get the subdomain from it. The following code will retrieve the subdomain and redirect to a view by reversing the named url.
Put it in a middleware.py file in your app.
Make sure you set up the middleware in your settings.py file.
Make sure you've named your view in urls.py
middleware.py
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
import re
subdomain_pattern = re.compile('(?P<subdomain>.*?)\..*?')
class SubdomainMiddleware(object):
def process_request(self, request):
match = subdomain_pattern.match(request.get_host())
subdomain = match.group('subdomain')
redirect_url = reverse('groups_detail', args=[subdomain])
return HttpResponseRedirect(redirect_url)
urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^groups/(?P<name>.+)/$', 'groups.views.detail', {}, name='group_detail'),
)
Note: this code is untested.
Redirecting can alter the URL's appearance. If you want to avoid this, simply call the associated view, capture its result, and return it in an HttpResponse().
You need to handle this via your webserver. If you have Django urls like...
/users/<username>/
... then use rewrite rules in the webserver to map <username>.domain.com to domain.com/users/<username>/.
If you're using Apache, you can read up here. Otherwise, each webserver has their own conventions but all will support the notion of url rewrites.