ristre...@gmail.com
未讀,2016年4月28日 下午5:51:262016/4/28登入以回覆作者
登入以轉寄訊息
你的權限不足,無法在這個群組刪除訊息
該群組的電子郵件地址為匿名,或你需要檢視成員電子郵件地址的權限才能查看原始貼文
收件者:django...@googlegroups.com
Hi,
On Django 1.8 (at least, all I can currently check.)
The method walk_items at django/template/defaultfilters.py:682, uses a
look ahead that technically doesn't always work.
If you look at the function, and notice at the end this
if next_item:
yield next_item, None
That will yield back the next_item as if it's a string/leaf, with no
children, which IS NOT always the case. There is no check to see if
it has children, only item is checked.
Of course, in this use case, you are choosing to delete a single model
object, so it is safe to assume the first item in the walk will be a
string, and the next, if any, could be an array (children), or a
string (just the next item.) But, when recursively calling this
method on sublists, it is possible miss a list based simply on where
it comes in the items_list.
The problem is that the last case up there assumes because the
next_item wasn't a list, the next item after it won't be either,
because after that line, control goes back to top to get the "next"
element, after next_item, from the iterator.
I can't share code. But, if you create some levels of model
structure, I'm sure you can make this happen. I'm happy to help with
that, should it be necessary.
The fix I'm using ....
def walk_items(item_list):
class PushbackIterator(object):
def __init__(self, iter):
self.stash = []
self.iter = iter
def __iter__(self):
return self
def next(self):
if self.stash:
return self.stash.pop()
else:
return self.iter.next()
def push(self, item):
self.stash.append(item)
item_iterator = PushbackIterator(iter(item_list))
for item in item_iterator:
try:
next_item = next(item_iterator)
except StopIteration:
next_item = None
if not isinstance(next_item, six.string_types):
try:
iter(next_item)
except TypeError:
pass
else:
yield item, next_item
continue
yield item, None
if next_item:
item_iterator.push(next_item)
I monkey patched a fix for my project with this. Comments welcome.
Thanks
Gene