Vignette Thumbnail dans l'interface d'administration
Quand dans la classe Profile dans models.py, on choisit par exemple de rajouter un champ avatar = models.ImageField(...) pour une photo d´avatar par exemple, comment fait-on dans admin.py pour enregistrer (register) ce champs pour que dans l’interface d’administration, ce ne soit pas le chemin URL vers l´image qui apparaissent, mais une vignette Thumbnail de l’image ?
Bonjour,
Je l'ai déjà fait en customisant mon administration.
Voici ce que j'ai :
# models.py
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
zip_code = models.CharField(max_length=5)
thumbnail = models.ImageField(upload_to="thumb", null=True)
REQUIRED_FIELDS = ["email"]
objects = CustomManager()
Et dans mon fichier d'admin :
# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from account.models import CustomUser
from django.utils.html import format_html
class CustomUserAdmin(UserAdmin):
model = CustomUser
def thumbnail_preview(self, obj):
return format_html('<img src="{}" style="max-width:200px; max-height:200px"/>'.format(obj.thumbnail.url))
# Configuration de la liste des utilisateurs
list_display = ("email", "username", "zip_code", "is_staff", "is_active", "thumbnail_preview")
list_filter = ("email", "is_staff", "is_active",)
search_fields = ("email", "username", "zip_code",)
ordering = ("email",)
# Configuration du formulaire d'édition
fieldsets = UserAdmin.fieldsets + (
("Informations complémentaires", {"fields": ("zip_code", "thumbnail")}),
)
# Configuration du formulaire de création
add_fieldsets = (
(None, {
"classes": ("wide",),
"fields": (
"email", "username", "zip_code", "password1", "password2",
"is_staff", "is_active", "groups", "user_permissions", "is_superuser"
)}
),
)
admin.site.register(CustomUser, CustomUserAdmin)
J'utilise format_html avec ma méthode def thumbnail_preview(self, obj):.
Merci beaucoup pour votre retour. Dans mon cas l'avatar n'est pas dans le CustomUser mais dans une autre classe Profile liée au CustomUser par
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="Utilisateur")
Voici ma classe profile :
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, verbose_name="Utilisateur")
firstname = models.CharField(max_length=100, verbose_name="Prénom")
lastname = models.CharField(max_length=100, verbose_name="Nom de famille")
avatar = models.ImageField(upload_to='avatars/', verbose_name="Photo de profil")
telephone = PhoneNumberField(region="FR")
adresse = models.CharField(max_length=100, verbose_name="Adresse")
ville = models.CharField(max_length=100, verbose_name="Ville")
code_postal = models.CharField(max_length=10, verbose_name="Code postal")
pays = models.CharField(max_length=50, verbose_name="Pays")
Du coup pour l'adapter à mon cas
class ProfileAdmin(? que mettre ici ?):
model = Profile ?
def avatar_preview(self, obj):
return format_html('<img src="{}" style="max-width:200px; max-height:200px"/>'.format(obj.avatar.url))
C'est ça ?
Merci par avance.
François.
En gros tu peux appliquer le même principe mais tu hérites de ModelAdmin :
# admin.py
# Un modèle lambda autre que user avec de la customisation
@admin.register(Service)
class ServiceAdmin(admin.ModelAdmin):
list_display = ["project", "date", "time_spent", "billed", "total"]
list_filter = ["billed", "project"]
Je viens de te le faire :
Imagine un modele avec une image :
from django.db import models
class BlogPost(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
class BlogImage(models.Model):
image = models.ImageField(upload_to="blog")
Dans l'admin tu fais :
from django.contrib import admin
from .models import BlogPost, BlogImage
from django.utils.html import format_html
@admin.register(BlogImage)
class BlogImageAdmin(admin.ModelAdmin):
list_display = ["image", "image_preview"]
def image_preview(self, obj):
return format_html(f'<img src="{obj.image.url}" style="max-width:200px; max-height:200px"/>')
Donc dans ma précédente réponse j'ai dit une bêtise ^^
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte