django2集成xadmin list index out of range报错追踪和处理

版权声明:本文为博主原创文章,未经博主允许不得转载。喜欢的用小手点击文章下面的顶,不喜欢的点下踩 https://blog.csdn.net/sethcss/article/details/79768170

今天又搞起了django,个人爱好用最新版的,所以虽然比着老师的视频做,还是出了莫名其妙的问题

IndexError at /xadmin/goods/goods/add/
list index out of range

遇到了数组越界
贴下报错信息,当然这个看不出什么,数组越界,这菜鸟都能看懂的英文

Error during template rendering
In template /Users/seth/pyenv/imooc_env36/lib/python3.6/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28

{% if field|is_checkbox and form_show_labels %}

这里写图片描述

顺便上张图
一般人看到这里就懵了,反正只知道数组越界,天知道什么原因,然后把这个图贴给别人。
淡定,django的报错很详细的,往下看
这里写图片描述
很明显是时间这边出了问题
时间add_time的字段类型出了问题
先说下django的时间字段类型
有3个,这里直接贴网上的

需要了解跟时间相关的三个modelField,
DateTimeField和DateField和TimeField
存储的内容分别对应着datetime(),date(),time()三个对象。
    对于auto_now和auto_now_add。两者默认值都为False。
    auto_now=Ture,字段保存时会自动保存当前时间,但要注意每次对其实例执行save()的时候都会将当前时间保存,也就是不能再手动给它存非当前时间的值。
    auto_now_add=True,字段在实例第一次保存的时候会保存当前时间,不管你在这里是否对其赋值。但是之后的save()是可以手动赋值的。也就是新实例化一个model,想手动存其他时间,就需要对该实例save()之后赋值然后再save()。

随便拷贝了一句,大概只是介绍了auto_now和auto_now_add,和我们报错无关,这里只是拓展一下三个时间类型,
然后我们来看这datetime(),date(),time()3个对象

date “1000-01-01”到“9999-12-31” 3字节
time-838:59:59”到“838:59:59” 3字节
datetime “1000-01-01 00:00:00” 到“9999-12-31 23:59:59” 8字节

date :“yyyy-mm-dd”格式表示的日期值 
time :“hh:mm:ss”格式表示的时间值 
datetime: “yyyy-mm-dd hh:mm:ss”格式

修改时间格式为DateField,完美解决,
有些人不乐意了,按天的新增时间还有毛用,是的,问题解决了,但业务逻辑不对了

这里写图片描述

回到之前被忽略的xadmin的第80行代码报错提示
找到相关代码

return mark_safe('<div class="datetime clearfix"><div class="input-group date bootstrap-datepicker"><span class="input-group-addon"><i class="fa fa-calendar"></i></span>%s'
                         '<span class="input-group-btn"><button class="btn btn-default" type="button">%s</button></span></div>'
                         '<div class="input-group time bootstrap-clockpicker"><span class="input-group-addon"><i class="fa fa-clock-o">'
                         '</i></span>%s<span class="input-group-btn"><button class="btn btn-default" type="button">%s</button></span></div></div>' % (input_html[0], _(u'Today'), input_html[1], _(u'Now')))

input_html[1]就是报错的代码,因为input_html里只有一个元素,从报错信息里也能找到input_html的值
这里写图片描述
仔细看input_html长度是为1的,所以没办法取到值
再看上一行代码,作者是想通过用“\n”把input_html里的两个标签拆开,但两个标签之间没有换行,所以没能拆分,导致报错。

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('\n') if ht != '']

但是,作者当初这样写,肯定是能把两个拆开的,为什么忽然不行了呢?
这里写图片描述
我们来看看这个forms是哪个html的
ctrl点MultWidget进去
这里写图片描述
找到html了

{% spaceless %}{% for widget in widget.subwidgets %}{% include widget.template_name %}{% endfor %}{% endspaceless %}

里面就一句话,先补充一下spaceless标签

spaceless标签:

用法:{% spaceless %}…内容…{% endspaceless %}

含义:删除包围内容中的所有tab或者回车字符

所以自然xadmin那边的代码就错误了
来看下作者的提交记录
https://github.com/django/django/commit/47681af34447e5d45f3fdb316497cdf9fbd0b7ce
这里写图片描述
英文不太好,不过意思应该是空格会导致多个widget的时候显示有问题,所以就加了spaceless标签
问题找到了,
但是django毕竟是主框架,我们尽量不要动他的代码,
我们来修改xadmin的代码
原来使用\n分割的
我们把代码改成下面这样

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != '']
input_html[0] = input_html[0] + "/>"
input_html[1] = "<" + input_html[1]

原来的代码不要删,如图,注释掉就好

这里写代码片
但有人可能还不明白了,怎么date类型就不出错,其实上面写了,data是年月日,datetime是年月日时分秒就要2个widget显示了,所以就出问题了

文章参考https://blog.csdn.net/yuhan963/article/details/79167743,感谢作者

猜你喜欢

转载自blog.csdn.net/sethcss/article/details/79768170
今日推荐