@@ -716,6 +716,32 @@ def exists(self, *filters):
716716 return Exists (self .queryset ().filter (* filters ).values ("user_id" ))
717717
718718
719+ class ChannelModelQuerySet (models .QuerySet ):
720+ def create (self , ** kwargs ):
721+ """
722+ Create a new object with the given kwargs, saving it to the database
723+ and returning the created object.
724+ Overriding the Django default here to allow passing through the actor_id
725+ to register this event in the channel history.
726+ """
727+ # Either allow the actor_id to be passed in, or read from a special attribute
728+ # on the queryset, this makes super calls to other methods easier to handle
729+ # without having to reimplement the entire method.
730+ actor_id = kwargs .pop ("actor_id" , getattr (self , "_actor_id" , None ))
731+ obj = self .model (** kwargs )
732+ self ._for_write = True
733+ obj .save (force_insert = True , using = self .db , actor_id = actor_id )
734+ return obj
735+
736+ def get_or_create (self , defaults = None , ** kwargs ):
737+ self ._actor_id = kwargs .pop ("actor_id" , None )
738+ return super ().get_or_create (defaults , ** kwargs )
739+
740+ def update_or_create (self , defaults = None , ** kwargs ):
741+ self ._actor_id = kwargs .pop ("actor_id" , None )
742+ return super ().update_or_create (defaults , ** kwargs )
743+
744+
719745class Channel (models .Model ):
720746 """ Permissions come from association with organizations """
721747 id = UUIDField (primary_key = True , default = uuid .uuid4 )
@@ -800,6 +826,8 @@ class Channel(models.Model):
800826 "version" ,
801827 ])
802828
829+ objects = ChannelModelQuerySet .as_manager ()
830+
803831 @classmethod
804832 def get_editable (cls , user , channel_id ):
805833 return cls .filter_edit_queryset (cls .objects .all (), user ).get (id = channel_id )
@@ -874,6 +902,10 @@ def get_resource_size(self):
874902 return files ['resource_size' ] or 0
875903
876904 def on_create (self ):
905+ actor_id = getattr (self , "_actor_id" , None )
906+ if actor_id is None :
907+ raise ValueError ("No actor_id passed to save method" )
908+
877909 if not self .content_defaults :
878910 self .content_defaults = DEFAULT_CONTENT_DEFAULTS
879911
@@ -905,7 +937,7 @@ def on_create(self):
905937 if self .public and (self .main_tree and self .main_tree .published ):
906938 delete_public_channel_cache_keys ()
907939
908- def on_update (self ):
940+ def on_update (self ): # noqa C901
909941 from contentcuration .utils .user import calculate_user_storage
910942 original_values = self ._field_updates .changed ()
911943
@@ -929,14 +961,23 @@ def on_update(self):
929961 for editor in self .editors .all ():
930962 calculate_user_storage (editor .pk )
931963
932- # Delete db if channel has been deleted and mark as unpublished
933964 if "deleted" in original_values and not original_values ["deleted" ]:
934965 self .pending_editors .all ().delete ()
966+ # Delete db if channel has been deleted and mark as unpublished
935967 export_db_storage_path = os .path .join (settings .DB_ROOT , "{channel_id}.sqlite3" .format (channel_id = self .id ))
936968 if default_storage .exists (export_db_storage_path ):
937969 default_storage .delete (export_db_storage_path )
938970 if self .main_tree :
939971 self .main_tree .published = False
972+ # mark the instance as deleted or recovered, if requested
973+ if "deleted" in original_values :
974+ user_id = getattr (self , "_actor_id" , None )
975+ if user_id is None :
976+ raise ValueError ("No actor_id passed to save method" )
977+ if original_values ["deleted" ]:
978+ self .history .create (actor_id = user_id , action = channel_history .RECOVERY )
979+ else :
980+ self .history .create (actor_id = user_id , action = channel_history .DELETION )
940981
941982 if self .main_tree and self .main_tree ._field_updates .changed ():
942983 self .main_tree .save ()
@@ -946,13 +987,20 @@ def on_update(self):
946987 delete_public_channel_cache_keys ()
947988
948989 def save (self , * args , ** kwargs ):
949- if self ._state .adding :
990+ self ._actor_id = kwargs .pop ("actor_id" , None )
991+ creating = self ._state .adding
992+ if creating :
993+ if self ._actor_id is None :
994+ raise ValueError ("No actor_id passed to save method" )
950995 self .on_create ()
951996 else :
952997 self .on_update ()
953998
954999 super (Channel , self ).save (* args , ** kwargs )
9551000
1001+ if creating :
1002+ self .history .create (actor_id = self ._actor_id , action = channel_history .CREATION )
1003+
9561004 def get_thumbnail (self ):
9571005 return get_channel_thumbnail (self )
9581006
@@ -996,24 +1044,11 @@ def make_public(self, bypass_signals=False):
9961044
9971045 return self
9981046
999- def mark_created (self , user ):
1000- self .history .create (actor_id = to_pk (user ), action = channel_history .CREATION )
1001-
10021047 def mark_publishing (self , user ):
10031048 self .history .create (actor_id = to_pk (user ), action = channel_history .PUBLICATION )
10041049 self .main_tree .publishing = True
10051050 self .main_tree .save ()
10061051
1007- def mark_deleted (self , user ):
1008- self .history .create (actor_id = to_pk (user ), action = channel_history .DELETION )
1009- self .deleted = True
1010- self .save ()
1011-
1012- def mark_recovered (self , user ):
1013- self .history .create (actor_id = to_pk (user ), action = channel_history .RECOVERY )
1014- self .deleted = False
1015- self .save ()
1016-
10171052 @property
10181053 def deletion_history (self ):
10191054 return self .history .filter (action = channel_history .DELETION )
0 commit comments