Tout en travaillant sur le dépôt numérique ASU, je ai trouvé que je avais besoin de la capacité de déclencher des rappels lorsque la transaction a été commise. Les signaux de Django semblait être le mécanisme parfait, mais validation de la transaction et les signaux de restauration ne sont pas (comme d'écrire ces lignes) pris en charge dans le cadre de base. (Voir ces billets dans le numéro de suivi Django pour le fond: Ticket # 14050, Ticket # 14051)
Cependant, un point essentiel écrit par Gr & eacute; goire Cachet semble faire l'affaire. Il ajoute une mise en œuvre de signal personnalisé et le singe-patches fonctions d'envoyer des signaux de post_commit et post_rollback manipulation d'une transaction de Django.
django_transaction_signals est une application Django qui se étend que essentiel de la manière suivante:
- Ajoute une fonction defer () qui peut être utilisé dans une transaction de reporter l'exécution d'une fonction tant que la transaction se est engagé (je ai trouvé cela très utile pour déclencher des tâches de céleri qui dépendent des objets commis).
- Protège contre les gestionnaires de signaux mal élevés (ce est à dire ceux qui quittent la transaction en cours dans un sale état) et soulève un BadlyBehavedTransactionSignalHandlerError quand il détecte un gestionnaire de mauvaise conduite.
- Efface gestionnaires à la sortie de la transaction indépendamment de savoir si un commit, rollback, ou ne se est produite. Cette version corrige un problème où les gestionnaires pourraient se accumuler et être déclenché sur une transaction ultérieure.
Utilisation (de l'essentiel d'origine):
Vous devez vous assurer de charger cette avant d'utiliser des signaux.
Par exemple, ajoutez la ligne suivante à l'fichier __init__.py de votre projet:
django_transaction_signals d'importation
Ensuite, pour utiliser les signaux, créer une fonction et le lier au signal de post_commit:
d'opération d'importation django.db
def ma_fonction (** kwargs):
& Nbsp; # faire vos trucs ici
& Nbsp; passe
transaction.signals.post_commit.connect (ma_fonction)
Si vous êtes en utilisant des variables non-locales dans votre fonction de rappel, assurez-vous d'utiliser référence non faible ou vos variables pourraient être des ordures collectées avant que la fonction est appelée. Par exemple, dans un modèle de méthode save ():
def enregistrer (self, * args, ** kwargs):
& Nbsp; def ma_fonction (** kwargs):
& Nbsp; # faire vos trucs ici
& Nbsp; # accès variable self
& Nbsp; auto
& Nbsp; transaction.signals.post_commit.connect (ma_fonction, faible = False)
Fonction L'utilisation de defer ():
defer () enregistre une fonction à exécuter après la réussite de la transaction en cours (se il existe). Appel defer (func, * args, ** kwargs) se traduit par ce qui suit:
- Si une transaction est active, enregistrer un post-commit auditeur pour exécuter func (* args, ** kwargs)
- Si aucune transaction ne est active, exécutez func (* args, ** kwargs) immédiatement
Cet exemple montre une mise à jour d'un objet transactionnel modèle qui enregistre une tâche de céleri à exécuter lorsque la transaction est validée avec succès.
de tâche d'importation de celery.task
d'opération d'importation django.db
de django_transaction_signals importation defer
pysolr d'importation
@ Transaction.commit_on_success
def update_object (obj):
& Nbsp; # ... modifier et enregistrer l'objet ...
& Nbsp; defer (index_object.delay, obj)
& Nbsp; # ... faire un peu de travail supplémentaire dans la transaction ...
task
def index_object (obj):
& Nbsp; index_obj = {'id': obj.id}
& Nbsp; # ... construire objet index ...
& Nbsp; solr = pysolr.Solr ('http: // localhost: 8080 / solr')
& Nbsp; solr.add ([index_obj])
Exigences :
- Python
- Django
Commentaires non trouvées