66from django .contrib .auth import get_user_model
77from django .db .models .signals import pre_save
88
9- from auditlog . models import LogEntry
9+ from auditlog import get_logentry_model
1010
1111auditlog_value = ContextVar ("auditlog_value" )
1212auditlog_disabled = ContextVar ("auditlog_disabled" , default = False )
1313
1414
1515@contextlib .contextmanager
1616def set_actor (actor , remote_addr = None , remote_port = None ):
17- """Connect a signal receiver with current user attached."""
18- # Initialize thread local storage
1917 context_data = {
20- "signal_duid " : ( "set_actor" , time . time ()) ,
18+ "actor " : actor ,
2119 "remote_addr" : remote_addr ,
2220 "remote_port" : remote_port ,
2321 }
22+ return call_context_manager (context_data )
23+
24+
25+ @contextlib .contextmanager
26+ def set_extra_data (context_data ):
27+ return call_context_manager (context_data )
28+
29+
30+ def call_context_manager (context_data ):
31+ """Connect a signal receiver with current user attached."""
32+ LogEntry = get_logentry_model ()
33+ # Initialize thread local storage
34+ context_data ["signal_duid" ] = ("set_actor" , time .time ())
2435 auditlog_value .set (context_data )
2536
2637 # Connect signal for automatic logging
27- set_actor = partial (
28- _set_actor ,
29- user = actor ,
38+ set_extra_data = partial (
39+ _set_extra_data ,
3040 signal_duid = context_data ["signal_duid" ],
3141 )
3242 pre_save .connect (
33- set_actor ,
43+ set_extra_data ,
3444 sender = LogEntry ,
3545 dispatch_uid = context_data ["signal_duid" ],
3646 weak = False ,
@@ -47,29 +57,42 @@ def set_actor(actor, remote_addr=None, remote_port=None):
4757 pre_save .disconnect (sender = LogEntry , dispatch_uid = auditlog ["signal_duid" ])
4858
4959
50- def _set_actor (user , sender , instance , signal_duid , ** kwargs ):
60+ def _set_actor (auditlog , instance , sender ):
61+ LogEntry = get_logentry_model ()
62+ auth_user_model = get_user_model ()
63+ if "actor" in auditlog :
64+ actor = auditlog .get ("actor" )
65+ if (
66+ sender == LogEntry
67+ and isinstance (actor , auth_user_model )
68+ and instance .actor is None
69+ ):
70+ instance .actor = actor
71+ instance .actor_email = getattr (actor , "email" , None )
72+
73+
74+ def _set_extra_data (sender , instance , signal_duid , ** kwargs ):
5175 """Signal receiver with extra 'user' and 'signal_duid' kwargs.
5276
5377 This function becomes a valid signal receiver when it is curried with the actor and a dispatch id.
5478 """
79+ LogEntry = get_logentry_model ()
5580 try :
5681 auditlog = auditlog_value .get ()
5782 except LookupError :
5883 pass
5984 else :
6085 if signal_duid != auditlog ["signal_duid" ]:
6186 return
62- auth_user_model = get_user_model ()
63- if (
64- sender == LogEntry
65- and isinstance (user , auth_user_model )
66- and instance .actor is None
67- ):
68- instance .actor = user
69- instance .actor_email = getattr (user , "email" , None )
7087
71- instance .remote_addr = auditlog ["remote_addr" ]
72- instance .remote_port = auditlog ["remote_port" ]
88+ _set_actor (auditlog , instance , sender )
89+
90+ for key in auditlog :
91+ if key != "actor" and hasattr (LogEntry , key ):
92+ if callable (auditlog [key ]):
93+ setattr (instance , key , auditlog [key ]())
94+ else :
95+ setattr (instance , key , auditlog [key ])
7396
7497
7598@contextlib .contextmanager
0 commit comments