Reputation: 5478
I have two types of users. After a user logs in, I take the user to their user profile at /profile
Based on the type of user, their profile may contain different navigation items and forms. Is there an easier way to construct the navigation based on the user type instead of putting {% if %} tags everywhere in the template.
Upvotes: 1
Views: 322
Reputation: 405
Have you thought about using permissions for that? I do same with custom permissions. Easy part is that auth provides anything you need, and it's always there in request.
Very similar code to what Chris Patt proposed would be used:
def profile_view(request):
if request.user.has_perm('permission_codename_foo'):
template = 'path/to/foo_profile.html'
elif request.user.has_perm('permission_codename_bar'):
template = 'path/to/bar_profile.html'
else:
template = 'path/to/generic_profile.html' # if you want a default
return render_to_response(template, {'data': 'data'}, context_instance=RequestContext(request))
what's useful, is that you can protect your views using same permissions with decorators:
@permission_required('permission_codename_foo')
def foo():
#your view here
or if you want to check for permission alternatives:
#user_passes_test(lambda u: u.has_perm('permission_codename_foo') or u.has_perm('permission_codename_bar'))
def foo_or_bar():
#your view here
django creates whole bunch of default permissions as well named: app_name.add_modelname, app_name.change_modelname, and app_name.delete_modelname if you need to limit user's possibilities
If you need to change parts of templates, try {% include %} to load those parts from different files.
Upvotes: 1
Reputation: 239460
Not sure why @dm03514 deleted his answer, but I'll post something like it, since it would've been my thoughts as well.
If the templates are different enough, then you're right, branching all over the place is a bad idea. It'll just make your template a confusing mess. So just create a separate template for each user type. Then, in your view, you can choose one template or another to show based on the user type. For example:
Old-style function-based views:
def profile_view(request):
if request.user.get_profile().type == 'foo':
template = 'path/to/foo_profile.html'
elif request.user.get_profile().type == 'bar':
template = 'path/to/bar_profile.html'
else:
template = 'path/to/generic_profile.html' # if you want a default
return render_to_response(template, {'data': 'data'}, context_instance=RequestContext(request))
New-style class-based views:
class MyView(View):
def get_template_names(self):
if self.request.user.get_profile().type == 'foo':
return ['path/to/foo_profile.html']
elif self.request.user.get_profile().type == 'bar':
return ['path/to/bar_profile.html']
else:
return ['path/to/generic_profile.html']
I'm not sure how your user types are set up, but if it's based on a string value, you can even create something much more automated, like:
template = 'path/to/%s_profile.html' % request.user.get_profile().type
Then, just create a template for each type based on that naming scheme.
And, of course, each template can extend a base profile.html template, allowing you factor out some common functionality.
Upvotes: 2
Reputation: 12901
Create a profile model and link the user to this profile model. (via a foreign key)
The profile model will then have different attributes for different behaviours.
These different behaviours would then be exposed in the web application either by branching the template (as you say using if in the template) or returning different data to the template or being sent to javascript functions in the font end to modify behaviour
Another alternative is to direct users to different pages based of there profile. The challenge with this is different urls will be needed to different users. This may lead to lots of code duplication.
Upvotes: 1