I need to have a dynamic URL prefix for all URLs in my app.
I'm familiar with doing a static prefix, such as url(r'^myprefix/app', include('app.urls'))
.
Instead, I need the myprefix
to be dynamic, such as url(r'^(?P<prefix>\w+)/app', include('app.urls'))
.
That works, but here's the kicker. I don't want that prefix
to be sent as a keyword argument to all of the views. I want to be able to capture it and use it in Middleware or something similar.
To give my specific use case, we have software (this Django project) used to manage various testing labs. The app needs knowledge of which lab it is operating on.
Currently I'm doing this with the following:
class LabMiddleware(object):
def process_request(self, request):
request.current_lab = 'lab1' # Note that this is currently hard coded
The requirement states that the users be able to go to a URL such as http://host/<lab_name>/app
where the lab_name
would then get used in my LabMiddleware. Because of this, I obviously don't want to have to accept the lab_name
in every single one of my views as it's cumbersome and overkill.
UPDATE:
Building on what Sohan gave in his answer, I ended up using a custom middleware class:
urls.py
url(r'^(?P<lab_name>\w+)/', include('apps.urls')),
apps/urls.py
url(r'^app1/', include('apps.app1.urls', namespace='app1')),
middleware.py
class LabMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
lab_name = view_kwargs.get('lab_name')
if lab_name:
request.current_lab = Lab.objects.get(name=lab_name)
# Remove the lab name from the kwargs before calling the view
view_kwargs.pop('lab_name')
return view_func(request, *view_args, **view_kwargs)
settings.py
MIDDLEWARE_CLASSES = (
# Default Django middleware classes here...
'raamp.middleware.LabMiddleware',
)
This allowed me to have the lab name in the URL and to add it to the request. Then by removing it from view_kwargs
, it doesn't get passed on to the view function and everything works as I intended it.
Also note that the code I have above isn't the most optimized (e.g. I'm querying the database for every request). I stripped out the code I have for caching this as it's not important to showing how this problem was solved, but is worth mentioning that some improvements should be made to this code if you are using it in a production system.