cleliodpaula
cleliodpaula

Reputation: 827

try/except in django, good practices

This part of code represents a index of my web page eg: 127.0.0.1:8000/

def IndexView(request):
    try:
        profile = request.user.get_profile() 
    except User.DoesNotExist:
        return render_to_response('index.html',
                              {'request': request,},
                              context_instance=RequestContext(request))

    return render_to_response('index.html',
                  {'request': request, 'profile' : profile},
                  context_instance=RequestContext(request))  

Why i'm still getting this error on debug?

AttributeError at / 'AnonymousUser' object has no attribute 'get_profile'

thanks in advance

Upvotes: 0

Views: 6604

Answers (6)

thikonom
thikonom

Reputation: 4267

You are getting this error because this specific user is not logged in.

To prevent the error either use the @login_required decorator just over your view:

from django.contrib.auth.decorators import login_required

@login_required
def IndexView(request):
    ...

or:

def IndexView(request):
    if request.user.is_authenticated(): #check to use if user is logged in
        try:
            profile = request.user.get_profile() 
        except User.DoesNotExist:
            return render_to_response('index.html',
                              {'request': request,},
                              context_instance=RequestContext(request))

        return render_to_response('index.html',
                      {'request': request, 'profile' : profile},
                      context_instance=RequestContext(request))  

Upvotes: 0

Alex Hart
Alex Hart

Reputation: 1673

Just to let you know, that's not very dry code.

check it:

def index_view(request):
    context_data = {'request': request}
    try:
        context_data.update('profile': request.user.get_profile())
    except AttributeError:
        pass

    return render_to_response('index.html', context_data,
         context_instance=RequestContext(request))  

Also, I'd double check and make sure request isn't already included in context. You may not have to specifically put it into context here.

EDIT: Forgot to pass context_data to render_to_response, example updated.

Upvotes: -1

Burhan Khalid
Burhan Khalid

Reputation: 174622

You need to add this check:

from django.shortcuts import render

def index_view(request):

    if request.user.is_authenticated():
        profile = request.user.get_profile()
        return render(request,'index.html',{'profile': profile})
    else:
        return redirect('login/')

Or, you can use the built-in decorator which ensures that your view is only called with a logged in user:

from django.contrib.auth.decorators import login_required
from django.shortcuts import render

@login_required
def index_view(request):

    profile = request.user.get_profile()
    return render(request,'index.html',{'profile': profile})

If you use the login_required decorator you need to make sure you have a LOGIN_URL setting that points to the view that handles the login form for your site. By default this is /accounts/login/

I changed the method name to lowercase as CamelCase is usually for classes in Python. Also, you don't need two return statements since you are rendering the same template. Instead, in your index.html template you can do:

{% if profile %}
    You have a profile!
{% else %}
    You don't
{% endif %}

Tips and tricks with authentication are listed at the authentication entry in the documentation.

Upvotes: 5

Sam Dolan
Sam Dolan

Reputation: 32532

You need to check if the user is authenticated before you try to pull the profile through get_profile. You can also simplify your code quite a bit:

def IndexView(request):
    profile = request.user.is_authenticated() and request.user.get_profile() 

    return render_to_response('index.html',
                              {'request': request, 'profile': profile},
                              context_instance=RequestContext(request))

You don't need the except, because the User with always be there.

Upvotes: 0

Andrew Gorcester
Andrew Gorcester

Reputation: 19973

You are expecting a User.DoesNotExist error, but instead the code is throwing an AttributeError. This is because request.user is a real object -- an AnonymousUser object -- and accessing it does not cause an error, but an AnonymousUser has no profile.

Use the @login_required decorator instead, or catch the AttributeError, or adjust your code so that it actually does throw User.DoesNotExist.

Upvotes: 0

Sid
Sid

Reputation: 7631

Because a user isn't currently logged in. When you call get_profile it gets called on a default user provided by Django called AnonymousUser which doesn't have a get_profile method as it isn't a real user. It doesn't throw an exception I am assuming and hence you get an error. Try the same thing after logging in and it should be fine.

Upvotes: 0

Related Questions