一 问题说明
在创建Model的时候,如果存在类型是DateTimeField的字段,则在xadmin后端管理界面里,对该Model进行添加操作的时候,会报list index out of range。

这是上篇文章创建的Model:

class IDC(models.Model):
name = models.CharField(max_length=)
contact = models.CharField(max_length=)
phone = models.CharField(max_length=)
address = models.CharField(max_length=)
create_time = models.DateField(auto_now=True) def __str__(self):
return self.name class Meta:
verbose_name = "IDC机房"
verbose_name_plural = verbose_name

将该Model的create_time字段类型修改如下:

create_time = models.DateTimeField()

然后登录xadmin系统,进入“IDC机房”管理界面,点击添加按钮,即会重现该问题。

二 问题原因
首先,报错信息里已经指出了报错的代码:

venv\lib\site-packages\xadmin\widgets.py in render, line 80

按照提示的目录,找到具体的代码:

def render(self, name, value, attrs=None):
input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('\n') if ht != '']
# return input_html
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[], _(u'Today'), input_html[], _(u'Now')))

上面贴出来的最后一行代码就是widgets.py的第80行代码。

input_html[1]就是报错的代码,因为input_html里只有一个元素,从报错信息里也能找到input_html的值如下:

['<input type="text" name="create_time_0" class="date-field form-control '
'admindatewidget" size="10" required id="id_create_time_0" /><input '
'type="text" name="create_time_1" class="time-field form-control '
'admintimewidget" size="8" required id="id_create_time_1" />']

阅读代码后,可以看出下面这句代码是希望用“\n”把input_html里的两个标签拆开,但两个标签之间没有换行,所以没能拆分,导致报错。

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

但是,作者当初这样写,肯定是能把两个拆开的,为什么忽然不行了呢?

继续查看两个标签的生成代码,发现其来源于以下模板:

venv\Lib\site-packages\django\forms\templates\django\forms\widgets\multiwidget.html

该html模板代码如下:

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

spaceless标签:

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

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

看到spaceless,猜测问题就出在这个标签上,推测这个标签是Django后来的版本加上去的。

查看Django的代码提交记录,验证了猜测,在Django2.0.1版本和1.11.9版本,看到了追加spaceless标签的提交记录,提交记录如下:

https://github.com/django/django/commit/47681af34447e5d45f3fdb316497cdf9fbd0b7ce
https://github.com/django/django/commit/c1d57615ac60171a73e1922a48ebc27fe513357e

三 解决问题
方案一
既然问题是由于模板文件追加了spaceless标签导致的,那么删除spaceless标签,将模板代码改成如下形式,是不是就能解决问题呢?

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

答案是肯定的,确实可以解决问题。

不过,spaceless标签是Django作为bug修复追加的代码,不建议删除,删除后,不清楚在其他地方会不会出现问题。

方案二
既然“\n”不能拆分标签,那么就换一种拆分方式,使用“/><”拆分。

原代码:

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

修改后代码:

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

最新文章

  1. 【2014-05-06】C++ 设计模式----单例模式
  2. [引用]SQLServer占CPU100%
  3. SwitchCompat 修改颜色
  4. C++一个简单的类
  5. oracle 10G以上版本 树形查询新加的几个功能
  6. KM算法(二分图的最佳完美匹配)
  7. Android之NDK编程(JNI)
  8. BUG修改纪录
  9. CentOS下挂载U盘
  10. PL/SQL 编程(一)基础,变量,分支,循环,异常
  11. React Native &amp; Android &amp; iOS &amp; APK
  12. 20175221 2018-2019-2 《Java程序设计》第二周学习总结
  13. extract method
  14. c语言之sizeof的细节
  15. *** Collection &lt;__NSArrayM: 0x600000647380&gt; was mutated while being enumerated.
  16. MySQL 删除数据库中重复数据方法
  17. oracle查询语句查询增加一列内容
  18. jQuery 发送验证码倒计时按钮
  19. VMware克隆CentOS网络配置
  20. Python学习笔记010——形参与实参

热门文章

  1. ESP8266的RTOS版本ota在线升级基本流程及备忘
  2. Vscode LeetCode 教程
  3. 源码分析RocketMQ ACL实现机制
  4. 精通awk系列(11):awk的工作流程
  5. C#中的Skip()和Take()
  6. JavaWeb入门——Tomcat的目录结构
  7. 前端开发规范:3-CSS
  8. Dotnetcore安装nuget包时不能使用content中的文件
  9. 更新阿里yum源并重建缓存
  10. Mysql安装及常用命令