EDIT: (See end of post for the original text of the answer with the initial, simple idea.)
After being kindly stricken with a cluebat (see the OP s comment below), I find I can see more to the problem than before. Sorry it took so long. Anyway:
Would this kind of template be alright for you?
{% for mi in dyn_menu_items %}
{% if mi.authorised %}
<a href={{ mi.url }}>{{ mi.title }}</a>
{% endif %}
{% endfor %}
To make this work on the Python side, you could use RequestContext
in your views with a custom context processor setting the dyn_menu_items
variable appropriately. In case some background information is required, the Advanced Templates chapter of the Django Book introduces RequestContext
, shows how to use it with render_to_response
(kinda important :-)) etc.
Also, I guess at this point it could be useful to put the view functions responsible for the locked-up sections of your site in a list somewhere:
_dyn_menu_items = [(url1, view1, title1, perm1), ...]
Then you could map
a couple of functions, say prepare_pattern
and prepare_menu_item
across that list, having it work roughly like so:
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
These could be combined into a single function, of course, but not everybody would find the result more readable... Anyway, the output of map(prepare_menu_item, _dyn_menu_items)
would need to be a dictionary to be passed to your views by a helpful context processor (the figuring out of which, it being the slightly tedious bit here, I ll leave to you ;-)), whereas the output of map(prepare_pattern, _dyn_menu_items)
, let s call it dyn_menu_patterns
, would be used in patterns( , *dyn_menu_patterns)
, to be used in your URLconf.
I hope this makes sense and is of some help...
THE PRE-EDIT ANSWER:
Based on your short description, I m not sure what solution would be best for you... But if the permission_required
snippet does what you want, just not DRY-ly enough, how about rolling your own wrapper:
def ask_to_login(perm, view):
return permission_required(perm, login_url= /loginpage/ , view)
You could put this anywhere, including in URLconf. Then you could replace all mentions of /loginpage/
with reference to a variable defined towards the top of your URLs file and you d have yourself a solution with a single mention of the actual login URL, for one-place-only update of said URL should you have to move it around. :-)
Of course the views would still need to be wrapped explicitly; if that bothers you, you could try to make ask_to_login
into a decorator for easy wrapping at the definition site. (But perhaps it s really best not to do it, lest you force yourself to dig your views from under the decorator in case you need them undecorated at some point in the future.)