从ImageField的Django管理显示图像(Django Admin Show Image f

2019-09-01 12:50发布

虽然我可以显示list_display上传的图像是有可能做到这一点对每个模型页面(如你改变模型中的页面)?

快速样品模型应该是:

Class Model1(models.Model):
    image = models.ImageField(upload_to=directory)

默认的管理员显示上传的图片的URL而不是图像本身。

谢谢!

Answer 1:

当然。 在你的模型类添加一个方法,如:

def image_tag(self):
    return u'<img src="%s" />' % <URL to the image>
image_tag.short_description = 'Image'
image_tag.allow_tags = True

并在admin.py补充:

fields = ( 'image_tag', )
readonly_fields = ('image_tag',)

ModelAdmin 。 如果你想限制编辑的图像领域的能力,请务必将其添加到exclude的属性。

注意:使用Django 1.8和“IMAGE_TAG”只有在readonly_fields它没有显示。 由于只有在字段的IMAGE_TAG“,它给了未知领域的一个错误。 你需要它,无论是在田间和readonly_fields才能正确显示。



Answer 2:

In addition to the answer of Michael C. O'Connor

Note that in Django v.1.9

image_tag.allow_tags = True

is deprecated and you should use format_html(), format_html_join(), or mark_safe() instead

So if you are storing your uploaded files in your public /directory folder, your code should look like this:

Class Model1(models.Model):
    image = models.ImageField(upload_to=directory)

    def image_tag(self):
        return mark_safe('<img src="/directory/%s" width="150" height="150" />' % (self.image))

    image_tag.short_description = 'Image'

and in your admin.py add:

fields = ['image_tag']
readonly_fields = ['image_tag']


Answer 3:

它可以在管理员完成,而无需修改模型

from django.utils.html import format_html


class Model1Admin(admin.ModelAdmin):

    def image_tag(self, obj):
        return format_html('<img src="{}" />'.format(obj.image.url))

    image_tag.short_description = 'Image'

    list_display = ['image_tag',]

admin.site.register(Model1, Model1Admin)


Answer 4:

Django的1.9要显示的图像,而不是在编辑页面的文件路径,使用ImageWidget是很好的办法做到这一点。

from django.contrib.admin.widgets import AdminFileWidget
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from django.contrib import admin


class AdminImageWidget(AdminFileWidget):
    def render(self, name, value, attrs=None):
        output = []
        if value and getattr(value, "url", None):
            image_url = value.url
            file_name = str(value)
            output.append(u' <a href="%s" target="_blank"><img src="%s" alt="%s" /></a> %s ' % \
                          (image_url, image_url, file_name, _('Change:')))
        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))


class ImageWidgetAdmin(admin.ModelAdmin):
    image_fields = []

    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name in self.image_fields:
            request = kwargs.pop("request", None)
            kwargs['widget'] = AdminImageWidget
            return db_field.formfield(**kwargs)
        return super(ImageWidgetAdmin, self).formfield_for_dbfield(db_field, **kwargs)

用法:

class IndividualBirdAdmin(ImageWidgetAdmin):
    image_fields = ['thumbNail', 'detailImage']

图片将显示为域, thumbNaildetailImage



Answer 5:

随着Django的imagekit您可以添加任何像这样的图片:

from imagekit.admin import AdminThumbnail

@register(Fancy)
class FancyAdmin(ModelAdmin):
    list_display = ['name', 'image_display']
    image_display = AdminThumbnail(image_field='image')
    image_display.short_description = 'Image'

    readonly_fields = ['image_display']  # this is for the change form


Answer 6:

虽然在这里已经分享了一些不错的,功能性的解决方案,我觉得非形式标记,如辅助图像标记,属于模板,没有粘住上的Django表单控件或模型管理类生成。 更语义的解决方案是:

管理模板覆盖

注:显然,我的名声不够高后两个以上的简单链接,所以我在下面的文本创建的注释,其中包括在这个答案底部的相应的URL。

从Django管理站点文档 :

这是比较容易忽略其中很多管理模块用来生成一个管理网站的各个页面的模板。 你甚至可以覆盖一些这些模板为特定应用程序或特定模式。

Django的django.contrib.admin.options.ModelAdmin (命名空间下经常访问django.contrib.admin.ModelAdmin )提出了一系列可能的模板路径, Django的模板加载器从最具体到少所以为了。 这段代码是直接从复制django.contrib.admin.options.ModelAdmin.render_change_form

return TemplateResponse(request, form_template or [
    "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
    "admin/%s/change_form.html" % app_label,
    "admin/change_form.html"
], context)

因此,考虑到上述Django管理模板覆盖文件和模板搜索路径,假设一个已经创造了其定义模型类“文章”一个应用程序“的文章”。 如果想要覆盖或扩展只有默认的Django管理站点变化形式模型articles.models.Article ,一个将执行以下步骤:

  1. 创建的覆盖文件的模板目录结构。
    • 虽然文件没有提到它,模板加载器会在应用程序目录第一,如果APP_DIRS 1设置为True
    • 因为一个人想覆盖由应用程序标签和模型Django管理网站模板,生成的目录层次结构将是: <project_root>/articles/templates/admin/articles/article/
  2. 创建一个新的目录结构的模板文件(S)。
    • 只有admin变化形式需要被重写,从而创造change_form.html
    • 最后,绝对路径将是<project_root>/articles/templates/admin/articles/article/change_form.html
  3. 完全覆盖或者干脆延长默认的admin变化表单模板。
    • 我没能找到关于上下文数据提供给默认的admin网站Django文档中的任何信息模板,所以我不得不来看看Django的源代码。
      • 默认更改表单模板:github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html
      • 一些相关的语境词典的定义中可以找到django.contrib.admin.options.ModelAdmin._changeform_viewdjango.contrib.admin.options.ModelAdmin.render_change_form

我的解决办法

假设我的ImageField的模型属性名称为“文件”,我的模板覆盖来实现图像预览将类似于此:

{% extends "admin/change_form.html" %}

{% block field_sets %}
{% if original %}
<div class="aligned form-row">
    <div>
        <label>Preview:</label>
        <img
            alt="image preview"
            src="/{{ original.file.url }}"
            style="max-height: 300px;">
    </div>
</div>
{% endif %}
{% for fieldset in adminform %}
  {% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}

original似乎是从中生成所述的ModelForm模型实例。 顺便说一句,我通常不使用内联CSS,但它是不值得为一个单一的规则一个单独的文件。

资料来源:

  1. docs.djangoproject.com/en/dev/ref/settings/#app-dirs


Answer 7:

Django的用于Venkat KOTRA的2.1更新的答案 。 答案工作正常的Django的2.0.7及以下。 但给服务器的500错误(如果DEBUG=False )或提供

render() got an unexpected keyword argument 'renderer'

其原因是,在Django 2.1: Support for Widget.render() methods without the renderer argument is removed. 所以,PARAM renderer现在是强制性的。 我们必须更新功能render()AdminImageWidget包括PARAM renderer 。 而且它必须是经过attrs (前kwargs如果有的话):

class AdminImageWidget(AdminFileWidget):
    def render(self, name, value, attrs=None, renderer=None):
        output = []
        if value and getattr(value, "url", None):
            image_url = value.url
            file_name = str(value)
            output.append(u' <a href="%s" target="_blank"><img src="%s" alt="%s" /></a> %s ' % \
                      (image_url, image_url, file_name, _('Change:')))
        output.append(super(AdminFileWidget, self).render(name, value, attrs, renderer))
        return mark_safe(u''.join(output))


Answer 8:

这是它如何工作的Django的2.1,而无需修改models.py

在你的Hero模式,你有一个像场:

headshot = models.ImageField(null=True, blank=True, upload_to="hero_headshots/")

你可以像下面这样做:

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):

    readonly_fields = [..., "headshot_image"]

    def headshot_image(self, obj):
        return mark_safe('<img src="{url}" width="{width}" height={height} />'.format(
            url = obj.headshot.url,
            width=obj.headshot.width,
            height=obj.headshot.height,
            )
    )


文章来源: Django Admin Show Image from Imagefield