I tried out this change, and it works well.  I've created a ticket 
(http://code.djangoproject.com/ticket/6295) with a patch.

--Ned.
http://nedbatchelder.com

Ned Batchelder wrote:
> Malcolm, thanks for continuing this (I was away for a few days).  I 
> was thinking about the forloop internals as well, and it seems to me 
> that there's no reason the forloop dictionary needs to be completely 
> new each time around.  Why not change forloop to create a new 
> dictionary before the first iteration, then update the dictionary on 
> each iteration rather than replace it?
>
> BTW: this problem also plagues ifchanged: the docs say "check if a 
> value has changed from the last iteration of a loop", which I guess is 
> accurate, but I was surprised to find that it really only works if the 
> ifchanged tag is evaluated on every iteration of the loop.
>
> --Ned.
>
> Malcolm Tredinnick wrote:
>> Hey Ned,
>>
>> On Sat, 2007-12-29 at 08:27 +1100, Malcolm Tredinnick wrote:
>> [...]
>>   
>>>         def render(self, context):
>>>            if context[self.varname] == id(context['forloop']):
>>>               return self.nodelist_false.render(context)
>>>            context[self.varname] = id(context['forloop'])
>>>            return self.nodelist_true.render(context)
>>>     
>>
>> This guess is rubbish. The problem is that the context['forloop']
>> dictionary is a new instance for every iteration of the for-loop, so
>> there's nothing constant about that outer structure we can use.
>>
>> After a bit of sleep, some food and some time spent thinking about this
>> whilst doing other stuff today, there's a better solution (a.k.a one
>> that works) attached to this mail. I've even tested this one.
>>
>> During any for-loop, the only thing that remains constant is the
>> "parentloop" dictionary. That dictionary is created anew every time the
>> *parent* loop steps forwards, but it is referred to by reference for
>> each iteration of the inner loop. So we can stick a marker into the
>> parent loop's data structure (even when there's no parent loop, that
>> data structure is an empty dictionary).
>>
>> So, this implementation does depend a bit on the internals of the
>> ForNode, but that isn't a complete crime. Plus it's been hard to come up
>> with an alternative. Every time I thought of some tricky data structure
>> that seemed to do the trick, I was able to break it. A template fragment
>> such as
>>
>>         {% for x in data %}
>>            {% if x %}
>>               {% iffirst %} yes {% else %} no {% endfirst %}
>>            {% else %} fail {% endif %}
>>         {% endfor %}
>>         
>> given data = (0, 1, 1, 0) twice in succession (without recompiling), or
>> giving data = (0, 1, 1, 0) and data = (0, 0, 1, 0) on successive runs
>> (again, without recompiling) was enough to break most of my attempts.
>>
>> It's also not too hard to extend this to be check whether this is the
>> first time around the parent loop using a similar method, although
>> nested "iffirst" tags seems hard.
>>
>> Best wishes,
>> Malcolm
>>
>>   
>
> -- 
> Ned Batchelder, http://nedbatchelder.com
>   
>
> >

-- 
Ned Batchelder, http://nedbatchelder.com


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

Reply via email to