Supposedly a trivial task to server 403/404/500 error pages when using django-cms. Followed instructions on an old forum post to create this:
from cms.views import details
def custom_404(request):
response = details(request, 'page-not-found')
response.status_code = 404
return response
...
Urls.py has some lines like this:
handler404 = 'error_pages.views.custom_404'
...
From traceback django cms can't locate 404 page:
File "/home/username/.virtualenvs/venv/lib/python2.7/site-packages/cms/views.py", line 22, in _handle_no_page
raise Http404('CMS: Page not found for "%s"' % slug)
Http404: CMS: Page not found for "page-not-found"
Obviously added the required custom pages in django-cms with the slug: 'page-not-found'. Am I missing something obvious? Running on production server with debug=False. Running django-cms 2.4.2 (edit)
Perhaps it is better to just serve plain ol' error messages with hardcoded stylesheets?
After walking into countless walls over-thinking the issues, I just went with using the basic 403/404/500 handlers:
from django.utils.functional import curry
from django.views.defaults import *
handler500 = curry(server_error, template_name='500.html')
handler404 = curry(page_not_found, template_name='404.html')
handler403 = curry(permission_denied, template_name='403.html')
Created the templates for each error and put in absolute URLs for the stylesheets.
Problem solved. Wasted a bunch of time on something this trivial.
Here is a working (with DEBUG at True or False) 404 handler:
def handler404(request):
if hasattr(request, '_current_page_cache'):
delattr(request, '_current_page_cache')
response = details(request, '404')
response.status_code = 404
return response
EDIT / Easy solution
After more searching and thinking, an easier solution would be to create the default/standard 404.html, and therein use django-cms static placeholders...as easy as it gets!
Original (still working) Answer
After struggling updating my handler404 from an old cms project, and not finding any infos on this topic, and the accepted answer not being a real solution to the problem, I investigated and found a version that works in django-cms 3.4.
Worth noting
delete the _current_page_cache on the request
set request.current_page, or cms_tags will not use your 404 page and render empty
call the main cms details view for rendering the page
finally, call response.render() (as mentioned in comments)
The view
def handler404(request):
if hasattr(request, '_current_page_cache'): # we'll hit the cache otherwise
delattr(request, '_current_page_cache')
page = get_page_from_request(request, '404')
request.current_page = page # templatags seem to use this.
response = details(request, '404') # the main cms view
if hasattr(response, 'render'): # 301/302 dont have it!
response.render() # didnt know about this, but it's needed
response.status_code = 404 # the obvious
return response
Related
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
I'm trying to create a basic submit form (like the dajaxice's example) but i keep receiving a 404 error from firebug console:
404 NOT FOUND 386ms
"NetworkError: 404 NOT FOUND - http://<my_website>/dajaxice/maynard.maynard_core.subscribe/"
My project folder structure is
/maynard/maynard_core/
This folder contains the main files of the project (views.py, ajax.py etc etc... main django project folder)
Inside the ajax.py file, there's the subscribe method:
from dajax.core import Dajax
from dajaxice.core import dajaxice_functions
from dajaxice.decorators import dajaxice_register
from views import subscribe_search
from forms import SubscriptionForm, SendMailForm
from django.core.mail import send_mail
def subscribe(request, form):
if request.POST:
dajax = Dajax()
form = SubscriptionForm(form)
try:
if form.is_valid():
url = form.cleaned_data['url_sub']
what = form.cleaned_data['what_sub']
where = form.cleaned_data['where_sub']
mail = form.cleaned_data['email']
subscribe_search(url,what,where,mail)
dajax.assign('#sub_mess_top','innerHTML','Thank you for subscribing to the search')
else:
dajax.add_css_class('#sub_mess_top','text error-message')
dajax.assign('#sub_mess_top','innerHTML','Couldn\'t complete the request, try again!')
return dajax.json()
except:
dajax.add_css_class('#sub_mess_top','text warning-message')
dajax.assign('#sub_mess_top','innerHTML','You already saved this search')
return dajax.json()
dajaxice_functions.register(subscribe)
Which is then called via this js method
function send_form_top(){
data = $('#subscribe').serializeObject(true);
Dajaxice.maynard.maynard_core.subscribe(Dajax.process,{'form':data});
}
The form is a basic form with action "#" and onclick="send_form_top();"
I followed the installation and configuration guide (settings configured, urls configured etc etc etc), and it's a very 101 implementation.
in urls.py
from dajaxice.core import dajaxice_autodiscover
dajaxice_autodiscover()
...
django.conf.urls.defaults.url(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, django.conf.urls.defaults.include('dajaxice.urls')),
I added 'dajaxice' to my installed apps in settings.py, and DAJAXICE_MEDIA_PREFIX is 'dajaxice' (as in the docs).
Templates are fine too (since i have the dajaxice dynamically compiled js included)
But still i can't seem to be able to make it work. I checked throu the response headers, and this is what i get for the dajax.js file:
maynard_core: {
subscribe: function(callback_function, argv, custom_settings){
Dajaxice.call('maynard.maynard_core.subscribe', callback_function, argv, custom_settings);
},
...
This tells me that the submit method, which is in the ajax.py file inside maynard/maynard_core/ is actually included and the callback is correct too. I really don't know how to debug this any more, django logs shows nothing about it. Thanks all in advance, i'm really loosing my hair on this.
If you got a 404 error, definitely the problem is in your urls.py configuration.
There is any wildcard url above the dajaxice one? Try to put the dajaxice url conf on the beginning and see what happens.
Anyway... are your views.py, ajax.py, etc... inside any app? or all of them are in the root project folder. That could be the problem too.
I am deploying a Django webpage and I love the Django Debug 404 page and and the Django page when there is a python error. However these aren't appropriate for a webpage that is going online. So I have made a custom 404 page. However, for me, and my IP address, I want to still have the Django Debug pages come up. Is there anyway to do this if I set Debug to false?
You can define your own handler-view for 404s, by setting handler404 in your urlconf. The default handler404 is django.views.defaults.page_not_found, which basically just renders the 404.html template.
If you put this in your urlconf, it will show the "technical" 404 response (the nice yellow page) for a certain IP, and use Django's default 404-production view for other IPs:
import sys
from django.views.debug import technical_404_response
from django.views.defaults import page_not_found
def handler404(request):
if request.META['REMOTE_ADDR'] == 'YOUR_IP_ADDRESS':
exc_type, exc_value, tb = sys.exc_info()
return technical_404_response(request, exc_value)
else:
return page_not_found(request)
I would advise you to set up proper logging for you 404 errors. Django can e-mail or log 404s and exceptions for you that happens in your production environment for rules that you can specify.
See the documentation on error reporting and logging (The logging framework was added in 1.3)
If a user type a random url(http://testurl/cdsdfsd) for a site ,how to issue page not found.I there any changes settings.py or how to handle this..
The django tutorial and docs have sections you should read.
You need to override the default 404 view.
in your urlconf:
handler404 = 'mysite.views.my_custom_404_view'
By default, django is rendering a 404.html template. Crete this file anywhere where your templates are found. E.g. you can create templates directory in your django project root, then add it to the TEMPLATE_DIRS in settings.py:
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates/'),
)
another solution is to write your own middleware which will check if there was 404 response, and the to decide what to display. This is especially useful if you want to have a fallback solution (like static pages) or to play with the response and e.g. perform a search on the site and show possible options.
here is an example middleware from django.contrib.flatpages. it check if url is defined in the database, if so - returns this page if not, pass and return default response.
class FlatpageFallbackMiddleware(object):
def process_response(self, request, response):
if response.status_code != 404:
return response # No need to check for a flatpage for non-404 responses.
try:
return flatpage(request, request.path_info)
# Return the original response if any errors happened. Because this
# is a middleware, we can't assume the errors will be caught elsewhere.
except Http404:
return response
except:
if settings.DEBUG:
raise
return response
I'm using Django 1.1.1 stable. When DEBUG is set to True Django flatpages works correctly; when DEBUG is False every flatpage I try to access raises a custom 404 error (my error template is obviously working correctly).
Searching around on the internet suggests creating 404 and 500 templates which I have done.
I've added to FlatpageFallBackMiddleware to middleware_classes and flatpages is added to installed applications. Any ideas how I can make flatpages work?
The same happened to me until I found that the 404 view was sending a 200 status response. So all you have to do is add this in the view that handles your 404 response:
def 404_handler(request): ...
response = render_to_response('404.html', locals(), context_instance=RequestContext(request))
response.status_code = 404
return response
try to add FlatpageFallBackMiddleware before django.middleware.common.CommonMiddleware
and be sure, that your 404.html and 500.html are stored in the root of your templates dir (eg: templates/404.html)
The key is checking the order of your middleware. Middleware is executed in top-down order on the way in (request and view) and in bottom-out order on the way out (response and exception). So if you are getting to your 404 handler on what should be a perfectly reasonable flatpage URL then something is catching the 404 before the flatpages middleware is getting called.
Had the same error in a different context. The problem was caused by me changing file urls.py from
from django.conf.urls.defaults import *
to
from django.conf.urls.defaults import include, patterns
as suggested by pylint, but this omits handler404 and handler500 which are expected to be imported implicitly by import *.
so either adding those to import or just importing * as django documents suggest solved the issue.
Make an error handling view that prints a stacktrace import traceback;traceback.print_exc() instead of ignoring the error silently.