一次Django admin bug解决的思维过程

在访问admin的数据列表时出现错误,错误信息如下图:

Caught an exception while rendering: list index out of range

9 <div id="content-main">
10 {% block object-tools %}
11 {% if has_add_permission %}
12 <ul class="object-tools"><li><a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name|escape as name %}Add {{ name }}{% endblocktrans %}</a></li></ul>
13 {% endif %}
14 {% endblock %}
15 <div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
16 {% block search %}{% search_form cl %}{% endblock %}
17 {% block date_hierarchy %}{% date_hierarchy cl %}{% endblock %}
18 {% block filters %}{% filters cl %}{% endblock %}
19 {% block result_list %}{% result_list cl %}{% endblock %}
20 {% block pagination %}{% pagination cl %}{% endblock %}
21 </div>
22 </div>
23 {% endblock %}
24

由于我之前修改过这个表的数据,所以第一反应是因为修改了某些数据而导致的。
但是将数据恢复到之前的状态,错误还是出现,所以花了好长时间去查看数据恢复是否正确。
在确认数据完全恢复到以前的状态的时候,我就感到没什么办法了。

休息一会后,决定仔细看出现错误的Traceback,发现是在处理时间的时候出现列表越界错误。
出错的代码如下:

django/db/backends/util.py
    dates = d.split('-')
times = t.split(':')
seconds = times[2] #运行出错代码

于是怀疑是修改的数据的时间字段出错,所以又去仔细查看恢复后的数据的时间字段,发现都是,如下格式:2005-07-29 09:56:34,这种格式的数据在处理的时候是不会出错的,因为时间精确到了秒,分割后times[2]的值就是时间的秒数。
只好修改代码,打印多一些信息,以找到出错的数据的时间值。

修改后的代码如下:

    dates = d.split('-')
times = t.split(':')
print dates
print times[0], times[1], times[2]
seconds = times[2]

运行时控制台输出如下:

这样就定位到了出错的数据的时间字段的值,原来新加入的数据里有条数据的时间值为:2009-07-21 12:12:00(在SQLite Developer中显示的值)。
到这里就基本猜到了出错的原因了,应该是如果时间的值是00的话Sqlite在存储的时候为将00去掉。
使用Sqlite命令行查看数据,得到结果如下图:

这一结果证明了的我的想法。
将代码修改为:

    dates = d.split('-')
times = t.split(':')

if len(times) == 2:
times.append('0')
elif len(times) == 1:
times.append('0')
times.append('0')

seconds = times[2]

这样更改后如果数据插入时间发生在整点的话,程序可以正常运行。但如果时间是00:00:00的话,还是会报错。如果能够让Sqlite记录时间的时间不省略00,就不用修改程序。

得到的教训:
1 出错了一定要看Traceback,不要相当然的认为自己知道错误在哪;
2 调试的时候,灵活的使用 print 语句能帮助我们快速的找到出错的原因。

posted on 2009-07-26 20:58  ddper  阅读(391)  评论(0编辑  收藏  举报

导航