具有动态前缀的Django URL [英] Django URL with dynamic prefix

查看:28
本文介绍了具有动态前缀的Django URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为我的应用程序中的所有URL都添加一个动态URL前缀.

I need to have a dynamic URL prefix for all URLs in my app.

我熟悉执行静态前缀,例如 url(r'^ myprefix/app',include('app.urls')).

I'm familiar with doing a static prefix, such as url(r'^myprefix/app', include('app.urls')).

相反,我需要 myprefix 是动态的,例如 url(r'^(?P< prefix> \ w +)/app',include('app.urls')).

Instead, I need the myprefixto be dynamic, such as url(r'^(?P<prefix>\w+)/app', include('app.urls')).

那行得通,但这是关键.我不希望将 prefix 作为关键字参数发送到所有视图.我希望能够捕获它并在中间件或类似软件中使用它.

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.

要给出我的特定用例,我们有用于管理各种测试实验室的软件(此Django项目).该应用程序需要了解它在哪个实验室进行操作.

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

该要求指出,用户能够访问诸如 http://host/< lab_name>/app 之类的URL,然后 lab_name 在我的LabMiddleware中使用.因此,我显然不想在我的每个视图中都接受 lab_name ,因为它既麻烦又矫kill过正.

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.

更新:

基于Sohan给出的答案,我最终使用了一个自定义的中间件类:

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',
)

这使我可以在URL中包含实验室名称,并将其添加到请求中.然后通过将其从 view_kwargs 中删除,它不会传递给视图函数,并且一切都会按我的预期进行.

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.

推荐答案

您可以创建包装每个视图函数的装饰器.装饰器可以处理您在lab name参数上所做的所有处理工作,并且每个视图都不需要查看 lab_name 参数.

You can create a decorator that wraps each view function. The decorator can take care of any processing work you have on the lab name parameter, and every view won't need to see the lab_name param.

def process_lab_name(request, lab_name):
    request.current_lab = lab_name

def lab(view_func):
    def _decorator(request, lab_name, *args, **kwargs):
        # process the lab_name argument
        process_lab_name(request, lab_name)
        # when calling the view function, exclude the lab_name argument
        response = view_func(request, *args, **kwargs)
        return response
    return wraps(view_func)(_decorator)

@lab
def some_view(request):
    return render(...)

您的路线将类似于 url(r'^(?P< lab_name> \ w +)/app'

这篇关于具有动态前缀的Django URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆