- Published on
Django Admin에서 이미지 미리보기 구현하는 방법
- Authors
- Name
- hongreat
- ✉️hongreat95@gmail.com
Django admin에서 이미지 필드(ImageField)의 이미지를 바로 미리보기로 확인할 수 있도록 만드는 간단한 방법 입니다. Inline의 경우 설정이 조금 다른데, 어떤 방식으로 이미지를 보여지게 할 수 있는지 공유합니다.
기본적으로 모델에 ImageField 이 있어야합니다. 다음과 같은 모델이 있다고 가정합니다.
class Product(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='products/')
1. Admin에서 미리보기 추가
Django admin에서 HTML을 안전하게 표시하기 위해 주로 format_html을 사용하는 것이 좋습니다. 예전에 스택오버플로우에서 알게되어 mark_safe를 활용하기도 했었는데, mark_safe는 직접 HTML을 삽입하기 때문에 XSS 취약성이 있어 주의가 필요하다고 합니다.
- format_html은 변수를 자동으로 HTML 이스케이프 처리하여 XSS 위험을 방지합니다. (format_html 이 훨씬 간편하기도 하니, 사용하는 것이 좋은 것 같습니다.)
admin.py에 미리보기 메서드를 추가합니다.
from django.contrib import admin
from django.utils.html import format_html
from .models import Product
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ['name', 'image_preview']
@admin.display(description="이미지 미리보기")
def image_preview(self, obj):
if obj.image:
return format_html('<img src="{}" style="max-height: 100px;" />', obj.image.url)
return "-"
2. Inline 모델에서 이미지 미리보기 추가
기본 admin.ModelAdmin에서 이미지 미리보기를 추가하는 방법외에 실제로 Inline을 통해서 세부페이지를 구현하는 경우가 종종 있습니다. 위의 방식대로 list_display를 사용하면 Inline에서는 이미지 미리보기가 적용되지 않습니다.
InlineAdmin(TabularInline 등)에서는 list_display가 아닌 fields와 readonly_fields를 이용해 이미지 미리보기를 구현 해야합니다.
class ProductImageInline(admin.TabularInline):
model = Product
extra = 0
fields = ['name', 'image', 'image_preview']
readonly_fields = ['image_preview']
@admin.display(description="이미지 미리보기")
def image_preview(self, obj):
if obj.image:
return format_html('<img src="{}" style="max-height: 100px;" />', obj.image.url)
return "-"
3. 이미지가 보이지 않는 경우
settings.py 혹은 MEDIA 설정을 꼭 확인합니다. 스토리지가 잘못설정된 경우도 더러 있을 수 있습니다.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# urls.py에서 아래처럼 urlpatterns에 추가되어 있는지 확인합니다.
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)