Makina Blog
Présentation de Django-Safedelete
Masquage d'objets en base de données une alternative à la suppression définitive.
Présentation
Pour beaucoup de "Djangonautes", un besoin récurrent est d'avoir la possibilité de masquer des objets avec l'ORM Django, au lieu de les supprimer définitivement. En réponse à ce besoin l'application django-safedelete a été développée.
Dans cette optique de masquage, des comportements différents peuvent être nécessaires selon les situations : - Nous pouvons vouloir simuler le comportement habituel de suppression de données, en masquant les objets supprimés. Ainsi, ces objets ne seront plus accessibles lors de futures requêtes, comme cela aurait été le cas s'ils avaient été réellement supprimés. - Dans le cas d'une suppression en cascade, nous avons la possibilité de masquer - au lieu de supprimer - les objets concernés par la cascade. Les objets qui en dépendent pourront toujours pointer vers lui. - Nous pouvons aussi supprimer un élément, sauf si d'autres en dépendent, auquel cas celui-ci sera simplement masqué. Pratique pour un site d'e-commerce, où la suppression d'articles provoquerait juste leur masquage pour éviter de nouveaux achats, en permettant toujours d'accéder à ceux-ci s'ils sont référencés dans des commandes. - IL est possible également de protéger un élément contre la suppression pour qu'il ne soit jamais masqué ou supprimé.
Bien entendu, lors de la suppression un comportement peut être forcé. Quand, une liste d'objets est récupèrée, nous pouvons aussi choisir de récupérer les articles masqués.
L'application est disponible sur github et pypi.
L'application expose des mixins, dont vos modèles Django doivent hériter. Un exemple est disponible dans le README, et une documentation est en ligne.
La technique
Cette application s'inspire de django-logicaldelete, mais ce projet ne propose pas de choisir entre plusieurs comportements (pas de masquage en cascade notamment). Le projet MozTrap (qui sert de base aux projets de Mozilla) possède un modèle de base qui intègre également cette fonction et va plus loin en stockant des dates et d'autres informations générales. Mais tout comme logicaldelete, il n'est pas générique puisqu'il ne propose qu'un seul comportement fixé.
Le mixin que l'application fournit contient un champ datetime deleted
, qui indique si l'objet a été masqué ou non (`None` pour un objet non masqué, la date du masquage sinon).
Il surcharge également la méthode delete()
en supprimant ou en masquant l'objet, selon le comportement souhaité.
La base est donc plutôt simple. Mais creusons un petit peu…
Nous nous rendons compte que nous allons devoir aussi remplacer la méthode delete()
des QuerySet que renvoie notre manager, puisque par défaut elle va supprimer tous les objets de la base de données.
En plus de définir notre propre manager, il nous faut donc aussi définir nos propres querysets.
Problème : si nous utilisons aussi des applications comme GeoDjango, qui utilisent leur propre type de managers/querysets, cela devient plus complexe à résoudre.
Pour pallier ce problème, des mixins de managers/queryset sont disponibles. Il faudra alors créer le manager du modèle en héritant à la fois du manager de django-safedelete et de l'autre app concernée.
Formations associées
Formations Django
Formation Django avancé
À distance (FOAD) Du 9 au 13 décembre 2024
Voir la formationActualités en lien
Utiliser des fonctions PostgreSQL dans des contraintes Django
Cet article vous présente comment utiliser les fonctions et les check constraints
PostgreSQL en tant que contrainte sur vos modèles Django.
Comment migrer vers une version récente de Django ?
Que ce soit pour avoir les dernières fonctionnalités ou les correctifs de sécurité, rester sur une version récente de Django est important pour la pérennité de son projet.
Le projet Agrégateur : fusionner des bases de données Geotrek
Le partage et la diffusion des données font partie des problématiques historiques au cœur du projet Geotrek.