[Django]-Get view function from request uri?

49๐Ÿ‘

โœ…

You can use the resolve method provided by django to get the function. You can use the __module__ attribute of the function returned to get the app label. This will return a string like project.app.views. So something like this:

from django.urls import resolve

myfunc, myargs, mykwargs = resolve("/hello_world/")
mymodule = myfunc.__module__

In case one needs the class of the view since a class based view is being used one can access the view_class of the returned function:

view_class = myfunc.view_class
๐Ÿ‘คKillianDS

7๐Ÿ‘

From Django 2.0 onward django.core.urlresolvers module has been moved to django.urls.

You will need to do this:

from django.urls import resolve

myfunc, myargs, mykwargs = resolve("/hello_world/")
mymodule = myfunc.__module__
๐Ÿ‘คbitsapien

5๐Ÿ‘

Since Django 1.3 (March 2011) the resolve function in the urlresolvers module returns a ResolverMatch object. Which provides access to all attributes of the resolved URL match, including the view callable path.

>>> from django.core.urlresolvers import resolve
>>> match = resolve('/')
>>> match.func
<function apps.core.views.HomeView>
>>> match._func_path
'apps.core.views.HomeView'
๐Ÿ‘คMatt

1๐Ÿ‘

1. Generate a text file with all URLs with corresponding view functions

./manage.py show_urls --format pretty-json --settings=<path-to-settings> > urls.txt

example
./manage.py show_urls --format pretty-json --settings=settings2.testing > urls.txt

2. Look for your URL in the output file urls.txt

    {
        "url": "/v3/affiliate/commission/",
        "module": "api.views.affiliate.CommissionView",
        "name": "affiliate-commission",
    },
๐Ÿ‘คpymen

1๐Ÿ‘

All the others focus on just the module or string representation of the view. However, if you want to directly access the view object for some reason, this could be handy

resolve('the_path/').func.cls

This gives the view object itself, this works on class based view, I havenโ€™t tested it on a function based view though.

๐Ÿ‘คreindeer

0๐Ÿ‘

Based on KillianDSโ€™s answer, hereโ€™s my solution:

from django.core.urlresolvers import resolve

def response(request, template=None, vars={}):
    if template is None:
        view_func = resolve(request.META['REQUEST_URI'])[0]
        app_label = view_func.__module__.rsplit('.', 1)[1]
        view_name = view_func.__name__
        template = '%s.html' % os.path.join(app_label, view_name)
    return render_to_response(template, vars, context_instance=RequestContext(request))

Now you can just call return response(request) at the end of your view funcs and it will automatically load up app/view.html as the template and pass in the request context.

๐Ÿ‘คmpen

Leave a comment