2

Using notfound_view_config in pyramid with parameter append_slash=True, i get 302 http status when redirecting, but i want set custom http status - 301.

@notfound_view_config(append_slash=True, renderer="not_found.mako") def notfound(request): return {}

okuznetsov
  • 278
  • 1
  • 5
  • 12

2 Answers2

2

The HTTPFound seems to be hard-coded in AppendSlashNotFoundViewFactory, but you may use its code as an inspiration for your "not found view":

from pyramid.interfaces import IRoutesMapper
from pyramid.compat import decode_path_info

@notfound_view_config(renderer="not_found.mako")
def notfound(request):
    path = decode_path_info(request.environ['PATH_INFO'] or '/')
    registry = request.registry
    mapper = registry.queryUtility(IRoutesMapper)
    if mapper is not None and not path.endswith('/'):
        slashpath = path + '/'
        for route in mapper.get_routes():
            if route.match(slashpath) is not None:
                qs = request.query_string
                if qs:
                    qs = '?' + qs
                raise HTTPMovedPermanently(location=request.path+'/'+qs)
    return {}

(untested, treat as pseudocode)

Sergey
  • 11,892
  • 2
  • 41
  • 52
  • AppendSlashNotFoundViewFactory makred as deprecated in pyramid version 1.3 – okuznetsov Jul 22 '14 at 08:06
  • I've borrowed the code from Pyramid 1.5b1 and I can't see it being deprecated there. At any rate - my code does not use `AppendSlashNotFoundViewFactory` at all - it just uses it as example of how to iterate over your route declarations trying to find one that matches. – Sergey Jul 22 '14 at 20:03
1

My solution with deprecated class:

class append_slash_notfound_factory(AppendSlashNotFoundViewFactory): def __call__(self, context, request): result = super(append_slash_notfound_factory, self).__call__(context, request) if isinstance(result, HTTPFound): return HTTPMovedPermanently(result.location) return result

okuznetsov
  • 278
  • 1
  • 5
  • 12