zoukankan      html  css  js  c++  java
  • 解决Python3.6.5+Django2.0集成xadmin后台点击添加或者内容详情报 list index out of range 的错误

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

    这是上篇文章创建的Model:

    class IDC(models.Model):
    name = models.CharField(max_length=64)
    contact = models.CharField(max_length=32)
    phone = models.CharField(max_length=32)
    address = models.CharField(max_length=128)
    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机房”管理界面,点击添加按钮,即会重现该问题。

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

    venvlibsite-packagesxadminwidgets.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('
    ') 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[0], _(u'Today'), input_html[1], _(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" />']

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

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

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

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

    venvLibsite-packagesdjangoforms emplatesdjangoformswidgetsmultiwidget.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修复追加的代码,不建议删除,删除后,不清楚在其他地方会不会出现问题。

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

    原代码:

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

    修改后代码:

    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]



  • 相关阅读:
    APC 注入
    远程线程注入突破SESSION 0
    .Net审计之.Net Json反序列化
    PHP审计之BEESCMS审计案例
    Thinkphp5学习笔记
    mysql 必知必会整理—触发器[十五]
    mysql 必知必会整理—游标[十四]
    mysql 必知必会整理—存储过程[十三]
    mysql 必知必会整理—视图[十二]
    mysql 必知必会整理—表[十一]
  • 原文地址:https://www.cnblogs.com/zmdComeOn/p/11966117.html
Copyright © 2011-2022 走看看