Custom Error Pages for django-cms
Asked Answered
V

3

10

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?

Vesper answered 30/9, 2013 at 9:5 Comment(0)
V
9

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.

Vesper answered 30/9, 2013 at 18:26 Comment(1)
actually, there is a real solution for your original question. even two of them, an old one, that would have worked when your question was asked (as I was updating a legacy system), and a super easy, django-cms > 3.0 version. I think it's worth having a "404 that is easily editable through the cms by your users/editors"...Gyrfalcon
S
3

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
Sassoon answered 1/4, 2014 at 12:42 Comment(1)
actually this resolution works. BUT note that you'll have to 'return response.render()' in oder to get the pageRodent
G
0

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
Gyrfalcon answered 13/6, 2017 at 10:59 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.