Home > Programming > 在Django的admin表单中显示图片

在Django的admin表单中显示图片

2009/11/25 2 Comments »

这几天又在折腾admin这颗Django皇冠上的明珠…
这次折腾的还是跟附件相关,不过主要是图片,也就是在表单里显示上传的图片。

查看了一下Django admin的模板,发现对于表单的处理,只用了几个简单的条件判断和循环:

?View Code PYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<fieldset class="module aligned {{ fieldset.classes }}">
  {% if fieldset.name %}
<h2>{{ fieldset.name }}</h2>
{% endif %}
  {% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}
  {% for line in fieldset %}
<div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} ">
      {{ line.errors }}
      {% for field in line %}
          {% if field.is_checkbox %}
              {{ field.field }}{{ field.label_tag }}
          {% else %}
              {{ field.label_tag }}{{ field.field }}
          {% endif %}
          {% if field.field.field.help_text %}
{{ field.field.field.help_text|safe }}
{% endif %}</div>
{% endfor %}
  {% endfor %}
</fieldset>

并没有出现对表单元素的相关处理,也就是说相关表单元素的已经在{{ field.label_tag }}{{ field.field }}中包装好,模板只负责显示,遂转移目标。

翻文档,在ModelAdmin Options里发现formfield_overrides,用法如下:

?View Code PYTHON
1
2
3
4
5
6
7
8
9
10
11
from django.db import models
from django.contrib import admin
 
# Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel
 
class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }

也就是说可以用widget的方式来进行包装,继续翻Django的代码,发现奥秘:在Django/contrib/admin/widgets.py中,有对各种input的包装!哈,有戏,于是自己写了一个widget,其实也就是原本照搬Django自带的那个AdminFileWidget,将其中的a改成img:

?View Code PYTHON
1
2
3
4
5
6
7
8
def render(self, name, value, attrs=None):
        output = []
        if value and hasattr(value, "url"):
            output.append('%s <img src="%s" alt="" />
%s ' % \
                (_('Currently:'), value.url,  _('Change:')))
        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))

然后在formfield_overrides中填写自己写的这个widget即可。

但是这样做有个问题,就是使用formfield_overrides处理的话,表单中所有的同类型input(比如上面的TextField)都会被这么包装一次,这显然是不行的,那怎么解决呢?
别着急,在在ModelAdmin Options里还有一个参数,就是ModelAdmin.form,可以自定义一个form,而不是Django admin默认调用model生成表单,那就好办了,参照这里就可以很简单的重写指定的一个input,避免上面的情况~~~

应为Django的资料相对来说比较少(特别是中文资料),加上自己对Django了解也比较肤浅,实现上面的这个效果费了小周折,不过通过这次,对Django的代码结构有了进一步的了解,相信以后应用起来要轻松很多了~~

Tags: ,

Comments:1

Leave my own
  1. 小桑
    2009/11/28 at 12:59

    围观

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks:1

Listed below are links to weblogs that reference 在Django的admin表单中显示图片

pingback from Django的數據庫遷移工具 | I'm TualatriX 2009/11/27

[...] 顺便再推荐一篇lfeng同学的教学文:在Django的admin表单中显示图片 [...]