@@ -977,7 +977,7 @@ def create_commands(self):
977977 command .full_clean ()
978978 with transaction .atomic ():
979979 command .save ()
980- except Exception as e :
980+ except ValidationError as e :
981981 self .skipped_devices [str (device .pk )] = (
982982 e .messages if hasattr (e , "messages" ) else [str (e )]
983983 )
@@ -1006,48 +1006,52 @@ def calculate_and_update_status(self):
10061006 - All commands completed successfully: status set to "success".
10071007 - Status unchanged: no database write performed.
10081008 """
1009- stats = self .batch_commands .aggregate (
1010- total_operations = models .Count ("id" ),
1011- in_progress = models .Count (
1012- models .Case (
1013- models .When (status = "in-progress" , then = 1 ),
1014- output_field = models .IntegerField (),
1015- )
1016- ),
1017- completed = models .Count (
1018- models .Case (
1019- models .When (~ models .Q (status = "in-progress" ), then = 1 ),
1020- output_field = models .IntegerField (),
1021- )
1022- ),
1023- successful = models .Count (
1024- models .Case (
1025- models .When (status = "success" , then = 1 ),
1026- output_field = models .IntegerField (),
1027- )
1028- ),
1029- failed = models .Count (
1030- models .Case (
1031- models .When (status = "failed" , then = 1 ),
1032- output_field = models .IntegerField (),
1033- )
1034- ),
1035- )
1036- if stats ["total_operations" ] == 0 :
1037- if self .skipped_devices :
1009+ with transaction .atomic ():
1010+ batch = self .__class__ .objects .select_for_update ().get (pk = self .pk )
1011+ stats = batch .batch_commands .aggregate (
1012+ total_operations = models .Count ("id" ),
1013+ in_progress = models .Count (
1014+ models .Case (
1015+ models .When (status = "in-progress" , then = 1 ),
1016+ output_field = models .IntegerField (),
1017+ )
1018+ ),
1019+ completed = models .Count (
1020+ models .Case (
1021+ models .When (~ models .Q (status = "in-progress" ), then = 1 ),
1022+ output_field = models .IntegerField (),
1023+ )
1024+ ),
1025+ successful = models .Count (
1026+ models .Case (
1027+ models .When (status = "success" , then = 1 ),
1028+ output_field = models .IntegerField (),
1029+ )
1030+ ),
1031+ failed = models .Count (
1032+ models .Case (
1033+ models .When (status = "failed" , then = 1 ),
1034+ output_field = models .IntegerField (),
1035+ )
1036+ ),
1037+ )
1038+ if stats ["total_operations" ] == 0 :
1039+ if batch .skipped_devices :
1040+ new_status = "failed"
1041+ else :
1042+ new_status = "idle"
1043+ elif stats ["in_progress" ] > 0 :
1044+ new_status = "in-progress"
1045+ elif stats ["failed" ] > 0 :
10381046 new_status = "failed"
1047+ elif (
1048+ stats ["successful" ] > 0
1049+ and stats ["completed" ] == stats ["total_operations" ]
1050+ and not batch .skipped_devices
1051+ ):
1052+ new_status = "success"
10391053 else :
1040- new_status = "idle"
1041- elif stats ["in_progress" ] > 0 :
1042- new_status = "in-progress"
1043- elif stats ["failed" ] > 0 :
1044- new_status = "failed"
1045- elif (
1046- stats ["successful" ] > 0 and stats ["completed" ] == stats ["total_operations" ]
1047- ):
1048- new_status = "success"
1049- else :
1050- new_status = self .status
1051- if self .status != new_status :
1052- self .status = new_status
1053- self .save (update_fields = ["status" ])
1054+ new_status = batch .status
1055+ if batch .status != new_status :
1056+ batch .status = new_status
1057+ batch .save (update_fields = ["status" ])
0 commit comments