| 1126 | |
| 1127 | |
| 1128 | class FeatureStateValue( |
| 1129 | AbstractBaseFeatureValueModel, |
| 1130 | SoftDeleteExportableModel, |
| 1131 | abstract_base_auditable_model_factory(["uuid"]), # type: ignore[misc] |
| 1132 | ): |
| 1133 | related_object_type = RelatedObjectType.FEATURE_STATE |
| 1134 | history_record_class_path = "features.models.HistoricalFeatureStateValue" |
| 1135 | |
| 1136 | # After a FeatureState is created, a FeatureStateValue is |
| 1137 | # automatically created in a post create hook. |
| 1138 | feature_state = models.OneToOneField( |
| 1139 | FeatureState, related_name="feature_state_value", on_delete=models.CASCADE |
| 1140 | ) |
| 1141 | |
| 1142 | objects = FeatureStateValueManager() # type: ignore[misc] |
| 1143 | |
| 1144 | def clone(self, feature_state: FeatureState) -> "FeatureStateValue": |
| 1145 | clone = deepcopy(self) |
| 1146 | clone.id = None |
| 1147 | clone.uuid = uuid.uuid4() |
| 1148 | clone.feature_state = feature_state |
| 1149 | clone.save() |
| 1150 | return clone |
| 1151 | |
| 1152 | def copy_from(self, source_feature_state_value: "FeatureStateValue"): # type: ignore[no-untyped-def] |
| 1153 | # Copy feature state type and values from given feature state value. |
| 1154 | self.type = source_feature_state_value.type |
| 1155 | self.boolean_value = source_feature_state_value.boolean_value |
| 1156 | self.integer_value = source_feature_state_value.integer_value |
| 1157 | self.string_value = source_feature_state_value.string_value |
| 1158 | self.save() |
| 1159 | |
| 1160 | def get_skip_create_audit_log(self) -> bool: |
| 1161 | try: |
| 1162 | if self.feature_state.deleted_at: |
| 1163 | return True |
| 1164 | |
| 1165 | return self.feature_state.get_skip_create_audit_log() |
| 1166 | |
| 1167 | except FeatureState.DoesNotExist: |
| 1168 | return True |
| 1169 | |
| 1170 | def get_update_log_message(self, history_instance) -> typing.Optional[str]: # type: ignore[no-untyped-def] |
| 1171 | fs = self.feature_state |
| 1172 | |
| 1173 | # NOTE: We have some feature state values that were created before we started |
| 1174 | # tracking history, resulting in no prev_record. |
| 1175 | changes = ( |
| 1176 | history_instance.diff_against(history_instance.prev_record).changes |
| 1177 | if history_instance.prev_record |
| 1178 | else [] |
| 1179 | ) |
| 1180 | if ( |
| 1181 | len(changes) == 1 |
| 1182 | and changes[0].field == "string_value" |
| 1183 | and changes[0].old in (None, "") |
| 1184 | and changes[0].new in (None, "") |
| 1185 | ): |
no test coverage detected
searching dependent graphs…