如何在Django Admin中展示Book模型关联的BookImage图片?
在Django Admin中展示Book详情及关联的BookImage图片
我有两个Django模型Book和BookImage,其中BookImage以Book为外键,一个Book对应多张图片。模型代码如下:
class Book(models.Model): name = models.CharField(max_length=100) description = models.CharField(max_length = 5000) class BookImage(models.Model): book = models.ForeignKey('Book', on_delete=models.CASCADE) image = models.ImageField(upload_to=settings.MEDIA_RELATIVE_ROOT + "/bookimages")
基于Python 3.7.12、Django 3.2.14版本,可通过以下两种方式在Admin面板实现需求:
方法一:内嵌图片管理(支持编辑)
利用Django Admin的InlineModelAdmin,可以在Book的编辑页面直接管理关联的BookImage,同时预览图片:
- 在应用的
admin.py中导入依赖:
from django.contrib import admin from django.utils.safestring import mark_safe from .models import Book, BookImage
- 定义BookImage的Inline类:
class BookImageInline(admin.TabularInline): model = BookImage extra = 1 # 默认显示1个新增图片的输入框 readonly_fields = ('image_preview',) def image_preview(self, obj): if obj.image: return mark_safe(f'<img src="{obj.image.url}" style="max-height: 150px; max-width: 150px;" />') return "无图片" image_preview.short_description = "图片预览"
- 注册Book模型并关联Inline:
@admin.register(Book) class BookAdmin(admin.ModelAdmin): list_display = ('name',) inlines = [BookImageInline]
配置完成后,进入Book的编辑页面,下方会展示所有关联的图片,支持预览、新增、编辑和删除操作。
方法二:仅在详情页展示图片
如果只需要查看Book关联的图片,不需要编辑功能,可以在Book的详情页添加自定义预览字段:
- 在
admin.py中编写BookAdmin类:
from django.contrib import admin from django.utils.safestring import mark_safe from .models import Book, BookImage @admin.register(Book) class BookAdmin(admin.ModelAdmin): list_display = ('name',) readonly_fields = ('book_images_preview',) def book_images_preview(self, obj): images = obj.bookimage_set.all() if not images: return "无关联图片" preview_html = "" for img in images: preview_html += f'<img src="{img.image.url}" style="max-height: 200px; max-width: 200px; margin: 10px;" />' return mark_safe(preview_html) book_images_preview.short_description = "关联图片"
这样在查看Book详情时,会展示所有关联的图片预览。
注意事项
- 确保已正确配置Django的媒体文件参数(
MEDIA_URL和MEDIA_ROOT),否则图片无法正常加载。 - 若开发环境需要访问媒体文件,需在项目
urls.py中添加媒体文件的路由配置:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 其他路由 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
内容的提问来源于stack exchange,提问作者Smith
相关产品推荐
相关产品推荐

