在Django的Admin Panel中显示ForeignKey的图像

时间:2017-12-13 10:59:55

标签: python django django-admin

我在项目中有两个类 - models models.py中的 处方 与外键相关的文件。以下是代码的一部分:

class Photo(models.Model):
    name = models.CharField(max_length=100,null=False)
    photo = models.ImageField(upload_to="photos/",null=True) 

    def photo_tag(self):
        return '<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.photo)
    photo_tag.short_description = 'Photo of prescription'
    photo_tag.allow_tags = True


class Prescription(models.Model):
    description = models.CharField(max_length=100,null=True)
    photo = models.ForeignKey(Photo, related_name='related_photo',null=True)

    def __str__(self):
        return self.description

我的 Admin.py

class PhotoAdmin(admin.ModelAdmin):
    list_display = ('name', 'photo_tag')
    fields = ('name','photo','photo_tag')     
    readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)

class PrescriptionAdmin(admin.ModelAdmin):
    list_display = ('get_photo')
    fields = ('photo','description')
    model = Prescription

    def get_photo(self, obj):
        return obj.photo.photo_tag
    get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)

问题是,当我在处方照片字段中打开处方列表而不是照片时,会显示以下消息。

<bound method Photo.photo_tag of <Photo: Photo object>>

如何在那里描述真实照片?

3 个答案:

答案 0 :(得分:1)

如果你要用html渲染图像(我猜你是这样的话),你能不能用姜以类似的方式显示描述?

<img src="{{photo.url}" title="{{photo.short_description}}" alt="{{photo.short_description}}">

请注意,我为互联网浏览器添加了alt,它似乎使用了alt而不是标题。

答案 1 :(得分:0)

您的方法几乎没有错误的问题。您的photo_tag方法应该是属性方法,或最终cached_property方法。为了安全地显示HTML代码,您应该使用Django提供的方法format_html

以下是我重构代码的方法:

<强> models.py

from django.db import models
from django.utils.html import format_html
from django.utils.functional import cached_property

class Photo(models.Model):
    name = models.CharField(max_length=100, null=False)
    photo = models.ImageField(upload_to="photos/", null=True)
    # better use blank=True instead of null=True for ImageField

    @cached_property
    def photo_tag(self):
        if self.photo:
            return format_html(
                '<a href="{img}"><img src="{img}"></a>',
                img=self.photo.url
            )
        return None # or better return '' if you use blank=True
    photo_tag.short_description = 'Photo of prescription'


class Prescription(models.Model):
    description = models.CharField(max_length=100, null=True)
    photo = models.ForeignKey(Photo, related_name='related_photo', null=True)

    def __str__(self):
        return self.description

现在,您可以将photo_tag用作Photo的属性,并在管理员中绑定HTML保险箱。

答案 2 :(得分:0)

感谢任何试图提供帮助的人。我在@Klaus的帮助下找到了另一个解决方案,他首先回答了我很确定可能还有更好的解决方案。以下是我更改代码的方法

Models.py

from django.utils.safestring import mark_safe

class Photo(models.Model):
    name = models.CharField(max_length=100,null=False)
    photo = models.ImageField(upload_to="photos/",null=True) 

    def photo_tag(self):
        return mark_safe('<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.photo))
    photo_tag.short_description = 'Photo of prescription'
    photo_tag.allow_tags = True


class Prescription(models.Model):
    description = models.CharField(max_length=100,null=True)
    photo = models.ForeignKey(Photo, related_name='related_photo',null=True)

    def __str__(self):
        return self.description

<强> Admin.py

class PhotoAdmin(admin.ModelAdmin):
    list_display = ('name', 'photo_tag')
    fields = ('name','photo','photo_tag')     
    readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)

class PrescriptionAdmin(admin.ModelAdmin):
    list_display = ('get_photo')
    fields = ('photo','description')
    model = Prescription

    def get_photo(self, obj):
        return obj.photo.photo_tag()
    get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)