Les imatges, en Django, necessiten un tractament particular.
Django processa eficientment les dades de l'aplicació, però no és ràpid per servir els arxius voluminosos com les imatges, o d'altres que es demanen molt sovint com els arxius estàtics (CSS, etc.).
Per això el tractament d'imatges té certes peculiaritats. Guardarem els binaris en una carpeta, típicament media/ i en producció deixarem que les serveixi el servidor web (Apache o Nginx). Django ho pot fer, però no és convenient.
Així, un esquena de posada en producció de Django seria quelcom similar a:
Per saber més podeu llegir sobre Django en produccio en aquesta wiki.
Instal·lar la biblioteca Pillow per al tractament d'imatges:
(env) $ pip install Pillow
Afegir el camp desijat als models
from django.db import models class Producte(models.Model): nom = models.CharField(max_length=100) imatge = models.ImageField(upload_to='productes/')
Configurar la carpeta de càrregues d'arxius (típicament media/) al settings.py:
import os MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Afegir la configuració a urls.py per servir els arxius media i estàtics quan estiguem en desenvolupament:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ... les teves URLs existents ... ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Personalitzar la vista a l'admin panel per veure les imatges:
from django.contrib import admin from django.utils.html import format_html from .models import Producte class ProducteAdmin(admin.ModelAdmin): # Afegeix el mètode a readonly_fields perquè es mostri en la pàgina d'edició readonly_fields = ('vista_previa_imatge',) # Defineix quins camps es mostren en el formulari d'edició fields = ('nom', 'imatge', 'vista_previa_imatge') def vista_previa_imatge(self, obj): if obj.imatge: # Retorna l'etiqueta HTML amb l'URL de la imatge return format_html('<img src="{}" width="200" height="150" style="object-fit: cover;" />', obj.imatge.url) return "No hi ha imatge" vista_previa_imatge.short_description = 'Previsualització' admin.site.register(Producte, ProducteAdmin)
I també podríem personalitzar la vista de llista de l'admin panel:
class ProducteAdmin(admin.ModelAdmin): list_display = ('nom', 'vista_previa_imatge') def vista_previa_imatge(self, obj): if obj.imatge: return format_html('<img src="{}" width="50" height="50" style="object-fit: cover;" />', obj.imatge.url) return "Sense imatge" vista_previa_imatge.short_description = 'Miniatura'