Accédant à la demande de l'utilisateur dans un post_save signal
Je l'ai fait ci-dessous post_save signal dans mon projet.
from django.db.models.signals import post_save
from django.contrib.auth.models import User
# CORE - SIGNALS
# Core Signals will operate based on post
def after_save_handler_attr_audit_obj(sender, **kwargs):
print User.get_profile()
if hasattr(kwargs['instance'], 'audit_obj'):
if kwargs['created']:
kwargs['instance'].audit_obj.create(operation="INSERT", operation_by=**USER.ID**).save()
else:
kwargs['instance'].audit_obj.create(operation="UPDATE").save()
# Connect the handler with the post save signal - Django 1.2
post_save.connect(after_save_handler_attr_audit_obj, dispatch_uid="core.models.audit.new")
La operation_by colonne, je veux obtenir le user_id et de les stocker. Aucune idée de comment faire?
- Il ya une raison pourquoi django ne veut pas que vous demande d'accès à l'objet dans les modèles et les signaux. Sa philosophie de la séparation des préoccupations seront violés.
Vous devez vous connecter pour publier un commentaire.
Ne peut pas être fait. L'utilisateur actuel n'est disponible que via la demande, ce qui n'est pas disponible lors de l'utilisation purement fonctionnalités du modèle. Accès de l'utilisateur dans la vue en quelque sorte.
post_save
. Le modèle qui est de l'enregistrement des données a un champ appeléuser
. Je suis à l'aide deinstance.user
pour cible l'utilisateur. Toutefois, la condition est qu'aucun utilisateur ne peut modifier d'autres utilisateurs les instances. Ainsi, l'utilisateur connecté est égale à lainstance.user
valeur.J'ai été capable de le faire par l'inspection de la pile et de la recherche de la vue, puis en regardant les variables locales de la vue de la demande. Il se sent comme un peu un hack, mais cela a fonctionné.
Ignacio est droit. Django du modèle signaux sont destinés à informer les autres composants du système sur les événements associés avec les instances et respectée des données, donc je suppose que c'est valide que vous ne pouvez pas, dire, demande d'accès aux données à partir d'un modèle
post_save
signal, à moins que la demande de données est stockée sur ou associée à l'instance.Je suppose qu'il ya beaucoup de façons de le gérer, allant du pire au meilleur, mais je dirais que c'est un premier exemple pour la création de la classe de base/fonction générique de points de vue qui permettra de gérer automatiquement pour vous.
Avoir votre point de vue qui héritent de
CreateView
,UpdateView
ouDeleteView
en outre hériter de votreAuditMixin
classe, si ils gèrent les verbes qui fonctionnent sur des modèles qui doivent être audités. LeAuditMixin
pouvez ensuite le crochet dans le point de vue qui a réussi à créer\update\supprimer des objets et créer une entrée dans la base de données.Sens parfait, très propre, facilement connectable et donne naissance à heureux poneys. Revers de médaille? Vous devrez être sur le bientôt-à-être-publié Django version 1.3 ou vous aurez à passer un peu de temps fiddlebending la fonction générique de vues et de fournir de nouvelles, pour chaque audit de l'opération.
Pour la traçabilité ajouter deux attributs à votre Modèle(
created_by
etupdated_by
), dans "updated_by" enregistrer le dernier utilisateur qui a modifié l'enregistrement. Puis dans votre signal que vous avez à l'utilisateur:models.py:
views.py
signals.py
Vous pouvez également utiliser django-réversion à cette fin, par exemple
Lire plus sur leur API https://django-reversion.readthedocs.io/en/stable/api.html#revision-api
Pourquoi ne pas ajouter un middleware avec quelque chose comme ceci :
et plus loin dans votre code (spécialement dans un signal dans le sujet) :
J'imagine que vous avez compris cela, mais j'ai eu le même problème et j'ai réalisé que tous les cas, j'ai créer avait une référence à l'utilisateur qui les crée (qui est ce que vous cherchez)
user_{pk}
et accès aux métadonnées. cela ne devrait pas créer une situation de concurrence, et donne le résultat escompté.Vous pouvez faire un petit hack en remplaçant le modèle de
save()
méthode et le paramétrage de l'utilisateur sur le sauvé instance comme paramètre supplémentaire. Pour obtenir de l'utilisateur, j'ai utiliséget_current_authenticated_user()
dedjango_currentuser.middleware.ThreadLocalUserMiddleware
(voir https://pypi.org/project/django-currentuser/).Dans votre
models.py
:Dans votre
signals.py
:PS: N'oubliez pas d'ajouter
'django_currentuser.middleware.ThreadLocalUserMiddleware'
à votreMIDDLEWARE_CLASSES
.