Weird Problem: Template Shows Templatevariable's Name Instead Of It's Value

7 views
Skip to first unread message

Schmidtchen Schleicher

unread,
Aug 14, 2011, 2:11:56 PM8/14/11
to django...@googlegroups.com
Hey Guys,
my problem is, as shown in the subject, that the template-engine puts in the name of the templatevariable instead of the value:

my view:

def YearlyView(request, calid, year):
    lst = []
    k = get_object_or_404(Kalender, pk=calid)
    now_year, now_month = datetime.date.today().year, datetime.date.today().month
    mlst = []
    for n, month in enumerate(mnames):
        entry = current = False
        entries = k.termin_set.filter(date__year=year, date__month=n+1)
   
        if entries:
            entry = True
        if year == now_year and n+1 == now_month:
            current = True
        mlst.append({'n':n+1, 'month':month, 'entry':entry, 'current':current})
   
    return render_to_response("kalender/year.html", {'months':mlst, 'user':request.user, 'yearh':year,'calid':calid})

Now i want to iterate through mlst alias 'months' in the template:

{% for current, entry, month, n in months %}
    <span class=
    {% if current %}"current"{% else %}
    "month{% endif %} >
    {% if entry %}<b>{% endif %}
    <a href="http://foo.bar/">{{ month }}</a>
    {% if entry %}</b>{% endif %}
</div> {% if n == 6 %} </br> {% endif %}

{# show content of the variables for debugging #}cur: {{ current }} entr: {{ entry }} mon: {{ month }} n: {{ n }} </br>

{% endfor %}

So there should be links with the name of the month, but instead there is:

month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n
month cur: current entr: entry mon: month n: n


So instead of "mon: Januar n: 1" etc. the names of the variables are displayed.

Why does it behave so and how to solve the problem?



And another question: In the view the order of the key-value-pairs in the dict mlst is set as 'n, month, entry, current' but in the template it is reversed...
Why?

Thanks for help...
And if I wrote too confusing, feel free to ask! ;-)

bruno desthuilliers

unread,
Aug 14, 2011, 3:57:20 PM8/14/11
to Django users
On 14 août, 20:11, Schmidtchen Schleicher <spiolli...@googlemail.com>
wrote:
> Hey Guys,
> my problem is, as shown in the subject, that the template-engine puts in the
> name of the templatevariable instead of the value:
>
> my view:
>
> def YearlyView(request, calid, year):

The convention is to use all_lower names for functions.

>     lst = []

This one isn't used anywhere

>     k = get_object_or_404(Kalender, pk=calid)
>     now_year, now_month = datetime.date.today().year,
> datetime.date.today().month

You make one useless call to datedatime.date.today here.

>     mlst = []

Readable names help.

>     for n, month in enumerate(mnames):

where does this mnames comes from ?

>         entry = current = False
>         entries = k.termin_set.filter(date__year=year, date__month=n+1)
>
>         if entries:
>             entry = True

If all you want to know is if there are entries for this year and
month, you could just use Queryset.count(). And directly evaluating it
as a boolean expression to avoid the useless if.

>         if year == now_year and n+1 == now_month:
>             current = True

Idem... Why write "if some_boolean_expression: x = True" when you can
write : "x = some_boolean_expression" ?

>         mlst.append({'n':n+1, 'month':month, 'entry':entry,
> 'current':current})

Clean code formatting helps too

>     return render_to_response("kalender/year.html", {'months':mlst,
> 'user':request.user,

You wouldn't need to pass request.user if you used a RequestContext
and the appropriate context processor.


def yearly_view(request, calid, year):
k = get_object_or_404(Kalender, pk=calid)

# local alias, will save a lot of computing...
termin_set = k.termin_set.filter

today = datetime.date.today()
now_year, now_month = today.year, today.month

month_list = []
for month_num, month_name in enumerate(month_names):
month_num +=1
has_entry = termin_set(
date__year=year,
date__month=month_num
).count() > 0
is_current = year == now_year and month_num == now_month
month_list.append({
'month_num':month_num,
'month_name':month_name,
'has_entry': has_entry,
'is_current':is_current
})

context = {
'month_list':month_list,
'user':request.user,
'year':year,
'calid':calid
}

return render_to_response(
"kalender/year.html",
context
)


> Now i want to iterate through mlst alias 'months' in the template:
>
> {% for current, entry, month, n in months %}

Please think about what "months" is here... Yes, a list of dicts. So
this line is the equivalent of:

current = months[0] # first dict in the list
entry = months[1] # second dict in the list
month = months[2] # etc....
n = months[3]


> And another question: In the view the order of the key-value-pairs in the
> dict mlst

It's *not* a dict. It's a list of dicts

> is set as 'n, month, entry, current' but in the template it is
> reversed...
> Why?


Python dicts are unordered.

Landy Chapman

unread,
Aug 14, 2011, 4:07:14 PM8/14/11
to Django users
Hi,
your template is missing a closing double-quote

this line
>     "month{% endif %} >
should be
>     "month"{% endif %} >


Also by reformatting a little I noticed you close a <span> with a </
div>

Jonas H.

unread,
Aug 14, 2011, 4:51:13 PM8/14/11
to django...@googlegroups.com
On 08/14/2011 09:57 PM, bruno desthuilliers wrote:
>> {% for current, entry, month, n in months %}
>
> Please think about what "months" is here... Yes, a list of dicts. So
> this line is the equivalent of:
>
> current = months[0] # first dict in the list
> entry = months[1] # second dict in the list
> month = months[2] # etc....
> n = months[3]

It is not. If you define multiple loop variables, Python will unpack
every item in the sequence into those variables -- so this code

for a, b in [...]:
...

is equivalent to

for item in [...]:
a, b = item
...

or

for item in [...]:
a = item[0]
b = item[0]
...

So what happens if your sequence is [{'foo': 1, 'bar': 2}]? The dict
gets unpacked into the loop variables:

for item in [{'foo': 1, 'bar': 2}]:
a, b = item

And what happens if you loop over a dict? You get a sequence of keys.
That's why in the OPs output, those keys will show up in the output.

@Schmidtchen: Use mlist.append([n+1, month, entry, current]) instead of
a dict and you're done -- that also solves the ordering issue.

And Bruno, Schmidtchen's code might really need some cleanup but that's
beyond the scope of this thread: You might have noticed that your
comments did *not help* the OP fixing his issues *at all*.

Oliver Schmidt

unread,
Aug 14, 2011, 5:15:03 PM8/14/11
to django...@googlegroups.com


Thank you very much!! I know my code needs to be tidied up xD. I'vd tried many things to solve the problem that's why my code looks so awful. And I'm glad there is an easy solution for my problem (and I didn't saw it *wall*)

And @bruno desthuilliers: It's good for a newbie like me to see how others would solve the problem. I will look if there is something I can do better.


Django has such a grea community. Thanks to everyone!

> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group. To post to this group, send email to
> django...@googlegroups.com. To unsubscribe from this group, send
> email to django-users...@googlegroups.com. For more options,
> visit this group at http://groups.google.com/group/django-users?hl=en.
>

Reply all
Reply to author
Forward
Message has been deleted
0 new messages