CoolGravatar
CoolGravatar

Reputation: 5478

Show different profile based on user type

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

Answers (3)

Marek
Marek

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

Chris Pratt
Chris Pratt

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

Matt Alcock
Matt Alcock

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

Related Questions