我需要为我的应用中的所有网址使用动态网址前缀。具有动态前缀的Django URL
我熟悉做一个静态前缀,如url(r'^myprefix/app', include('app.urls'))
。
相反,我需要myprefix
是动态的,如url(r'^(?P<prefix>\w+)/app', include('app.urls'))
。
这很有效,但这里是踢球者。我不希望将prefix
作为关键字参数发送给所有视图。我希望能够捕获它并将其用于中间件或类似的东西。
为了说明我的具体用例,我们使用软件(这个Django项目)来管理各种测试实验室。该应用程序需要知道它在哪个实验室上运行。
目前,我用下面这样:
class LabMiddleware(object):
def process_request(self, request):
request.current_lab = 'lab1' # Note that this is currently hard coded
要求指出,用户可以去一个URL,如http://host/<lab_name>/app
其中lab_name
随后将得到我的LabMiddleware使用。正因为如此,我显然不想接受lab_name
在我的每一个观点,因为它是繁琐和矫枉过正。
UPDATE:
建立在什么Sohan给他的回答,我结束了使用自定义的中间件类:
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
中删除它,它不会传递给视图函数,并且一切都按照我的意图工作。
另请注意,我上面的代码不是最优化的(例如,我正在为每个请求查询数据库)。我删除了用于缓存的代码,因为它不是显示如何解决此问题的重要信息,但值得一提的是,如果您在生产系统中使用此代码,则应对此代码进行一些改进。
IMO接受另一种说法为所有的视图功能是不是大材小用,只有最低限度的繁琐。我认为如果视图参数直接匹配routes.py – 2014-12-04 21:29:41
中的结构,你的应用将更易于维护和理解。问题是,对于每个单一视图函数,需要包含'lab_name'参数,则函数需要在每一个人都会被召唤来处理这些信息。对于大型应用程序(目前这是),这很麻烦并且容易出错,尤其是对于多个开发人员。最后,如果我不能以其他方式工作,那么这将是我将采取的实施,但我试图避免它。 – Jared 2014-12-04 21:34:52
我看到了 - 实际上一个好的解决方案可能是使用装饰器来代替。你的装饰器可以处理和“吞下”lab_name' arg。让我写一个例子... – 2014-12-04 21:44:36