2

I'm building a simple web application with Django. My users are separated into multiple groups, for example Group A, Group B, etc.

What I want to do is to dynamically update urlpatterns list in urls.py so that I can have different views on same url endpoints.

For example, I'd like to do something like this (I know syntax is off, it's just to demonstrate what I want)

urlpatterns = [
    url(r'^$', views.homepage, name='homepage'),
    url(r'^login/$', views.BaseLogin.as_view(), name='core.login'),
    url(r'^logout/$', views.logout, name='core.logout'),
]  + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if request.user in groupA:
    urlpatterns.append(url(r'^dash/', include('groupA.urls')))
else:
    urlpatterns.append(url(r'^dash/', include('groupB.urls')))

How would I best achieve this?

intelis
  • 7,829
  • 14
  • 58
  • 102

3 Answers3

4

I think this is neither possible nor desirable. You should place such logic in the view. Make both land in the same view and redirect or simply put together different content in the view based on the user's group affiliation.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Please take this advice. Include every url and if the user does not have permission for a certain URL just respond with an HTTP 404 or 403 – kevswanberg Mar 29 '16 at 20:46
2

URLs are not loaded dynamically for every user, they are parsed and loaded on application startup, so you cannot put per-request logic in there. In general, this logic should be handled in your view.

That said, you can simulate this behavior using custom middleware. Make a middleware class, write process_view() method to check your URL and if it one you are interested in, find and run the view function yourself and return the HttpResponse. Make sure your middleware is the last in the list, so every other middleware gets a chance to run before yours does. Mind you that this would fall under the "ugly hack" category in any serious project :)

Here is a link to relevant docs https://docs.djangoproject.com/en/1.9/topics/http/middleware/#process-view

Mad Wombat
  • 14,490
  • 14
  • 73
  • 109
  • If you're going to write a middleware, it would probably be better to set `request.urlconf` in `process_request`, rather than overriding `process_view`. – Alasdair Mar 29 '16 at 21:25
  • it seems that people have been having trouble rewriting requests in middleware, but it might be possible to do it this way as well – Mad Wombat Mar 29 '16 at 21:27
2

It's not a good idea to change urlpatterns dynamically, but you could create two url confs mysite/groupA_root_urls.py and mysite/groupB_root_urls.py.

You can then write a middleware that sets the request.urlconf attribute to either 'mysite.groupA_root_urls' 'mysite.groupA_root_urls'.

Django will then use that urlconf instead of the conf from the ROOT_URLCONF setting.

Alasdair
  • 298,606
  • 55
  • 578
  • 516