swizzard
swizzard

Reputation: 1095

Django KeyError {% if in %}

I'm teaching myself Django, and I'm trying to do a test thing such that a pre-existing user will get a page listing his or her "stuff," a new user will get a page informing him or her that they're not in the system, and a list of users can be generated. The problem is that I keep getting KeyErrors for any users not in the pre-existing users dictionary (it works fine if the user is in the dict). I'm not sure if the problem is in the way I've structured the relevant function in my views.py or in the way I'm using the templateTags, or what. Django's error page points to the context line of my views.py page, but I don't know if that's actually the problem.

Any help would be greatly appreciated.

My code:

views.py:

def hiUser(request,uname):
    t = get_template("samplate1.html")
    ds,ti = getTime()
    user_stuff = {"sam":["a","b","c"],"kathy":["foo","bar"],"rob":[]}
    c = Context({"date":ds,"time":ti,"user":uname,"user_stuff":user_stuff[uname],"users":user_stuff.keys()})
    return HttpResponse(t.render(c))

samplate1.html:

<html>
{% ifequal user "list" %}
<head><title>List of Users</title></head>
<body><h1>List of users</h1>
<ul>
{% for user in users %}
    <li>{{ user }}</li>
{% empty %}
    <p>No users listed!</p>
{% endfor %}
</ul>
{% endifequal %}
{% if user in users %}
<head><title>Greetings, {{ user }}</title></head>
<body>
<h1>Hello</h1>
<p>Greetings, {{ user }}</p>
<p>The date is {{ date }}</p>
<p>The time is {{ time }}</p>
<p>Here is a list of your stuff:</p>
<ul>
    {% for item in user_stuff %}
        <li>{{ item }}</li>
    {% empty %}
        <p>You don't have any stuff!</p>    
    {% endfor %}
    </ul>
{% else %}
<head><title>You're new here, huh?</title></head>
<body>
<h1>Hello</h1>
<p>Your username is not in our database.</p>
<p>You should probably fix that.</p>
{% endif %}

and finally:

urls.py:

...
urlpatterns = ('',
   (r'^user/name/(.*)/$',hiUser),
)

Upvotes: 1

Views: 363

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239290

Instead of user_stuff[uname] use user_stuff.get(uname). If the uname key doesn't exist, the value will be None. Or you can use user_stuff.get(uname, []), which will make it an empty list if it doesn't exist.

Upvotes: 1

girasquid
girasquid

Reputation: 15526

The problem is with your views.py - this part, specifically:

c = Context({"date":ds,"time":ti,"user":uname,"user_stuff":user_stuff[uname],"users":user_stuff.keys()})

In order to solve this, you need to figure out what you're going to do if a user isn't in user_stuff. Are you going to raise a 404? Display an error? Fill in dummy content?

If you want to raise a 404, you could do it like this:

from django.http import Http404

def hiUser(request,uname):
    t = get_template("samplate1.html")
    ds,ti = getTime()
    user_stuff = {"sam":["a","b","c"],"kathy":["foo","bar"],"rob":[]}

    if uname not in user_stuff:
        raise Http404

    c = Context({"date":ds,"time":ti,"user":uname,"user_stuff":user_stuff[uname],"users":user_stuff.keys()})
    return HttpResponse(t.render(c))

If you want to fill in dummy content, you could use dict.get, like this:

def hiUser(request,uname):
    t = get_template("samplate1.html")
    ds,ti = getTime()
    user_stuff = {"sam":["a","b","c"],"kathy":["foo","bar"],"rob":[]}

    stuff_for_user = user_stuff.get(uaname, [])
    c = Context({"date":ds,"time":ti,"user":uname,"user_stuff":stuff_for_user,"users":user_stuff.keys()})

    return HttpResponse(t.render(c))

If you want to display an error page, you'll want to modify the code sample that raises a 404.

Upvotes: 1

Related Questions