Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django state-based url routing

Hello!

I would love for a django app I am developing to route a URL to a response based on logic beyond just the URL string.

I would like to be able to take the state of the application (the logged in user and their session, the contents of the database) into account. This would mean that two users could visit exactly the same URL, but based on the type of account they have (for instance) they would receive different responses.

An example

Say my app has User and Admin user classes. They both will frequently visit http://some-domain.com/dashboard, but they will see entirely different things there. Furthermore, there will be sub-urls beyond dashboard like /dashboard/comments, /dashboard/friends. Again, these will be entirely different views depending on the user class.

At present I do something like this:

(urls.py)

urlpatterns = [
    url(r'^dashboard/', include([
        url(r'^$', render_dashboard),
        url(r'^settings/$', render_dashboard_settings),
        url(r'^friends/$', render_dashboard_friends),
    ])),
]

The issue with this setup is that there is no way to take the current user into account. It can still be made to work because I can route all kinds of user accounts to the same template, and use {% if ... %} statements there to provide different content to different users. I could also make the name of the template that ought to be rendered dynamic, in the call to django.shortcuts.render. But neither of these things are what I want. I want to be able to differentiate between users at an earlier level of URL mapping.

My question

What I do want to do is extend the functionality of the url method to take state into account, and route based on that functionality. Ideally, something like this:

urlpatterns = [
    user_class_based_url(r'', {

        'Admin': include([
            url(r'^dashboard/', include([
                url(r'^$', render_admin_dashboard),
                url(r'^settings/$', render_admin_dashboard_settings),
                url(r'^friends/$', render_admin_dashboard_friends),
            ])),
        ]),

        'User': include([
            url(r'^dashboard/', include([
                url(r'^$', render_user_dashboard),
                url(r'^settings/$', render_user_dashboard_settings),
                url(r'^friends/$', render_user_dashboard_friends),
            ])),
        ]),

        'SomeOtherUserClass': include([.....]),
    }),
]

Now, different renderer functions are being called for the same url, but different user classes. Unfortunately, user_class_based_url is something I have totally made up. Ideally, user_class_based_url would be a custom function I could write. That way I could write other similar functions that take the app's state into account in other ways.

QUESTION: Is there any way I can get this functionality?

In response to "you shouldn't even be designing it this way"

The example I have given is contrived to get my question across more quickly. I want the functionality I have described because it would be incredibly helpful in many ways for the app I am building, and I am sure it would be a better approach than the alternative.

Note

I am already using django rest framework, in case that can be used to implement this design.

like image 679
Gershom Maes Avatar asked Sep 27 '22 18:09

Gershom Maes


1 Answers

There isn't any way to do this in Django at the moment. Recently, there has been this discussion about creating a new API for the url dispatcher, but any changes would be in a future version of Django.

like image 187
Alasdair Avatar answered Oct 18 '22 19:10

Alasdair