carltongibson / neapolitan

Quick CRUD views for Django
https://noumenal.es/neapolitan/
MIT License
413 stars 30 forks source link

Multi-view URLResolver/RoutingView #2

Closed carltongibson closed 1 year ago

carltongibson commented 4 years ago

DRF handles multi-renderer cases well. But it struggles when you need different logic by content type. e.g. serving a traditional HTML view requires a redirect on POST that the API views do not. We might serve RSS, say, which again needs a different view implementation. And so on.

There are some ideas for implementing this:

Of these the routing view is the cleanest. But could it be pulled up into the URL resolver?

BaseHandler doesn't pass the request into the resolver, but it could:

    def resolve_request(self, request):
        """
        Retrieve/set the urlconf for the request. Return the view resolved,
        with its args and kwargs.
        """
        # Work out the resolver.
        if hasattr(request, 'urlconf'):
            urlconf = request.urlconf
            set_urlconf(urlconf)
            resolver = get_resolver(urlconf)
        else:
            resolver = get_resolver()
        # Resolve the view, and assign the match object back to the request.
        resolver_match = resolver.resolve(request.path_info)
        request.resolver_match = resolver_match
        return resolver_match

Is there any advantage to MultiResolver vs a suitably generic RoutingView? What does each look like?

To consider: we'd like to be able to apply middleware to parts of the site, at the URLConf level, rather than just the whole site, or individual views (to avoid putting if path_info == ... type logic in the middleware). If the box were open, how might we address that too?

carltongibson commented 4 years ago

Mailing list thread (with related tickets) on Adding tags to URLs.

What I'd like to do is apply middleware at the include() point, much like wrapping an individual view, but for a whole list of URLs. resolve() then returns the view callback, wrapped in the middleware to be applied.