编辑:(请参阅帖子末尾的原始答案的原始文本,简单的想法。)
在受到线索蝙蝠的好意(请参阅下面的 OP 评论)之后,我发现我可以比以前看到更多的问题。抱歉花了这么长时间。反正:
这种模板适合你吗?
{% for mi in dyn_menu_items %}
{% if mi.authorised %}
<a href={{ mi.url }}>{{ mi.title }}</a>
{% endif %}
{% endfor %}
为了在 Python 端进行这项工作,您可以RequestContext
在视图中使用自定义上下文处理器dyn_menu_items
适当地设置变量。如果需要一些背景信息,Django Book 的Advanced Templates章节介绍RequestContext
了如何使用它render_to_response
(有点重要:-))等。
另外,我想此时将负责站点锁定部分的视图函数放在某个列表中可能会很有用:
_dyn_menu_items = [(url1, view1, title1, perm1), ...]
然后你可以map
使用几个函数,比如prepare_pattern
在prepare_menu_item
那个列表中,让它大致像这样工作:
def prepare_pattern(menu_item):
url1, view, title, perm = menu_item
pattern = PREPARE_URLCONF_ENTRY_SOMEHOW(...) # fill in as appropriate
return pattern
def prepare_menu_item(menu_item):
url, view, title, perm = menu_item
mi = PREPARE_THE_BIT_FOR_REQUESTCONTEXT(...) # as above
return mi
当然,这些可以组合成一个函数,但并不是每个人都会发现结果更具可读性......无论如何,输出map(prepare_menu_item, _dyn_menu_items)
需要是一个字典,由有用的上下文处理器传递给您的视图(弄清楚其中,这里有点乏味,我会留给你;-)),而map(prepare_pattern, _dyn_menu_items)
我们称之为它的输出dyn_menu_patterns
将patterns('', *dyn_menu_patterns)
用于在你的 URLconf 中使用。
我希望这是有道理的,并有一些帮助......
预编辑答案:
根据您的简短描述,我不确定哪种解决方案最适合您……但是,如果该permission_required
片段可以满足您的要求,但不够干燥,那么滚动您自己的包装器如何:
def ask_to_login(perm, view):
return permission_required(perm, login_url='/loginpage/', view)
你可以把它放在任何地方,包括在 URLconf 中。然后,您可以参考在 URL 文件顶部定义的变量替换所有提及的内容'/loginpage/'
,并且您将拥有一个解决方案,只需提及实际的登录 URL,如果您只对所述 URL 进行一次更新必须移动它。:-)
当然,视图仍然需要显式包装;如果这让您感到困扰,您可以尝试制作ask_to_login
一个装饰器,以便在定义站点上轻松包装。(但也许最好不要这样做,以免你强迫自己从装饰器下面挖掘你的观点,以防你将来需要它们不装饰。)