Champ booléen et icône Django admin
Actuellement en plein développement d'une application Django, je me suis retouvé confronté à un petit problème "Comment faire pour afficher les icones de base d'un champ booléen dans l'administration de Django", quand celui-ci est éditable, je n'ai pas cherché bien longtemps je suis tombé sur cette question sur stackoverflow, la solution est simple mais ne fonctionne pas, je me suis donc inspiré de ce script pour en créer un et qui fonctionne bien sur la verison 1.6 de Django
Pour illustrer ma problematique voici à quoi ressemble un champ booléen non éditable (image de gauche) et un champ booléen éditable (image de droite) dans l'administration de django:
Ajout d'un script JS dans la Class Media
La solution est assez simple est nécessite la création d'un petit script JS, qui permettra d'ajouter les images à la place de la checkbox en question et ainsi de changer l'image lors des differents états (pas checked ou checked).
Commençons d'abord dans votre fichier admin.py, l'ajout de la classe Media dans le model qui intégre votre champ booléen, cela nous permettra d'ajouter notre script JS dans notre listing d'objets.
class Media: from django.conf import settings media_url = getattr(settings, 'MEDIA_URL')
js = (media_url + 'admin/bool_field_icons.js',
Ici j'ai simplement ajouter dans mon attribut js l'url de mon fichier qui s'appel bool_field_icons.js, vous devez bien entendu l'adapter à votre chemin et nom de votre script.
Développement du script JS
Voici le script JS en question et commenté:
(function($){ //Pour commencer on va initialiser 2 variables, qui vont stocker //chacune d'elle une image se référant aux différents états (pas selectionnée, et selectionnée) var on_image = '/static/admin/img/icon-yes.gif'; var off_image = '/static/admin/img/icon-no.gif'; $(document).ready(function(){ // On cherche tous les champ de type checkbox et on boucle en ajoutant une fonction $('input[type=checkbox]').each(function(){ // On check la class du body pour que seul la checkbox du listing soit affectée (change_list) var $body_class = $('body').attr('class').split(' ')[1]; var $this = $(this); var $id = $this.attr('id'); // Regex if checkbox id end by "active" var regex = /active$/; // on test si le regex a bien la chaine de caractère "active" et que la page n'est pas "change-form" if(regex.test($id) && $body_class != 'change-form') { // On ajoute la classe "checkbox-icon" $this.addClass('checkbox-icon'); // On cache les checkboxes" var $checkbox = $('.checkbox-icon#'+$id).hide(); var $img = $('img'); // condition suivant l'état on ajoute l'image correspondante if ($checkbox.attr('checked')) { $img.attr('src', on_image); $img.attr('alt', 'True'); } else { $img.attr('src', off_image); $img.attr('alt', 'False'); } $img.insertAfter($checkbox); // Ajoute de l'évenement "click" permettant au click l'ajout de la valeur // et du changement d'image $img.click(function(){ var $img = $(this); var $checkbox = $img.siblings('input'); if ($img.attr('src') == on_image) { $img.attr('src', off_image); $img.attr('alt', 'False'); $checkbox.attr('checked', false); } else { $img.attr('src', on_image); $img.attr('alt', 'True'); $checkbox.attr('checked', true); } }); } }); }); })(django.jQuery);
Biensur il faudra adapter le script en fonction de vos classes, etc.
Le script fonctionne sous Django 1.6.5 mais devrait fonctionner sur d'autres versions, à vous de personnaliser le script
comme bon vous semble.
SI vous avez des questions ou amélioration à suggérer n'hésitez à m'en faire par dans les commentaires.
Publié le: Mardi 30 septembre 2014