Django Admin Show Image来自Imagefield

Jef*_*_Hd 54 django django-admin

虽然我可以在list_display中显示上传的图像,但是可以在每个模型页面上执行此操作(如更改模型所获得的页面)?

快速样本模型将是:

Class Model1(models.Model):
    image = models.ImageField(upload_to=directory)
Run Code Online (Sandbox Code Playgroud)

默认管理员显示上传图像的网址,但不显示图片本身.

谢谢!

Mic*_*nor 107

当然.在您的模型类中添加如下方法:

def image_tag(self):
    from django.utils.html import escape
    return u'<img src="%s" />' % escape(<URL to the image>)
image_tag.short_description = 'Image'
image_tag.allow_tags = True
Run Code Online (Sandbox Code Playgroud)

并在您的admin.py添加中:

fields = ( 'image_tag', )
readonly_fields = ('image_tag',)
Run Code Online (Sandbox Code Playgroud)

到你的ModelAdmin.如果要限制编辑图像字段的功能,请务必将其添加到exclude属性中.

注意:只有readonly_fields中的Django 1.8和'image_tag'才会显示.仅在字段中使用'image_tag',它会产生未知字段的错误.您需要在字段和readonly_fields中才能正确显示.


pal*_*der 53

除了Michael C. O'Connor的回答

请注意,在Django v.1.9中

image_tag.allow_tags = True
Run Code Online (Sandbox Code Playgroud)

已弃用,您应该使用format_html(),format_html_join()或mark_safe()代替

因此,如果要将上载的文件存储在公共/目录文件夹中,则代码应如下所示:

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'
Run Code Online (Sandbox Code Playgroud)

并在您的admin.py中添加:

fields = ['image_tag']
readonly_fields = ['image_tag']
Run Code Online (Sandbox Code Playgroud)

  • @Sensei和palamunder,实际上有关于尾随逗号的区别 - 当元组只有一个对象时它们是_are_,或者它不被视为元组.试试`foo =('a'); bar =('b',); 打印foo,bar`,你会看到差异.我真的很惊讶Django示例使用非集合对象,但Django做了很多事情. (3认同)
  • 显然,只有在指定了所需的所有其他字段时才需要fields =('image_tag',).例如,如果您的模型具有20个属性,但您不想将所有属性可视化,则可以仅以这种方式指定您想要的那些属性.对逗号的痴迷只是为了避免错过一个如果你之后添加别的东西.它已被用于许多与Django相关的教程和书籍,无论如何,它不一定需要.我个人认为它很有用. (2认同)

Ser*_*jik 27

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

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)
Run Code Online (Sandbox Code Playgroud)


Ven*_*tra 16

对于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)
Run Code Online (Sandbox Code Playgroud)

用法:

class IndividualBirdAdmin(ImageWidgetAdmin):
    image_fields = ['thumbNail', 'detailImage']
Run Code Online (Sandbox Code Playgroud)

图像将显示为字段,thumbNaildetailImage


Ris*_*nha 9

使用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
Run Code Online (Sandbox Code Playgroud)


mon*_*nee 7

虽然这里已经分享了一些好的,功能性的解决方案,但我觉得非形式标记(例如辅助图像标记)属于模板,而不是添加到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)
Run Code Online (Sandbox Code Playgroud)

因此,考虑到前面提到的Django管理模板覆盖文档和模板搜索路径,假设有人创建了一个应用程序"文章",其中定义了一个模型类"文章".如果想要覆盖或扩展只有默认的Django管理站点变化形式模型articles.models.Article,一个将执行以下步骤:

  1. 为覆盖文件创建模板目录结构.
    • 虽然文档没有提到它,但如果设置为APP_DIRS1,模板加载器将首先查看app目录True.
    • 因为想要按应用标签和模型覆盖Django管理站点模板,所以生成的目录层次结构将是: <project_root>/articles/templates/admin/articles/article/
  2. 在一个新的目录结构中创建模板文件.
    • 只需要覆盖管理员更改表单才能创建change_form.html.
    • 最终的绝对路径将是 <project_root>/articles/templates/admin/articles/article/change_form.html
  3. 完全覆盖或只是扩展默认的管理员更改表单模板.
    • 我无法在Django文档中找到有关默认管理网站模板可用的上下文数据的任何信息,因此我不得不查看Django源代码.
      • 默认更改表单模板:github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html
      • 一些相关的上下文字典定义可以在django.contrib.admin.options.ModelAdmin._changeform_view和中找到 django.contrib.admin.options.ModelAdmin.render_change_form

我的解决方案

假设我的模型上的ImageField属性名称是"file",我实现图像预览的模板覆盖将类似于:

{% 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 %}
Run Code Online (Sandbox Code Playgroud)

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

资料来源:

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


Ale*_*lig 5

这就是django 2.1 的工作原理,无需修改models.py

在您的Hero模型中,您有一个图像字段:

headshot = models.ImageField(null=True, blank=True, upload_to="hero_headshots/")
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

@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,
            )
    )
Run Code Online (Sandbox Code Playgroud)


小智 5

我试图自己弄清楚,这就是我想出的

@admin.register(ToDo)
class ToDoAdmin(admin.ModelAdmin):
    def image_tag(self, obj):
        return format_html('<img src="{}" width="auto" height="200px" />'.format(obj.img.url))

    image_tag.short_description = 'Image'

    list_display = ['image_tag']
    readonly_fields = ['image_tag']
Run Code Online (Sandbox Code Playgroud)