| 459 | |
| 460 | |
| 461 | class FeatureState( |
| 462 | SoftDeleteExportableModel, |
| 463 | LifecycleModelMixin, # type: ignore[misc] |
| 464 | abstract_base_auditable_model_factory( # type: ignore[misc] |
| 465 | historical_records_excluded_fields=["uuid"], |
| 466 | change_details_excluded_fields=["live_from", "version"], |
| 467 | show_change_details_for_create=True, |
| 468 | ), |
| 469 | ): |
| 470 | history_record_class_path = "features.models.HistoricalFeatureState" |
| 471 | related_object_type = RelatedObjectType.FEATURE_STATE |
| 472 | |
| 473 | feature = models.ForeignKey( |
| 474 | Feature, related_name="feature_states", on_delete=models.CASCADE |
| 475 | ) |
| 476 | |
| 477 | environment = models.ForeignKey( |
| 478 | "environments.Environment", |
| 479 | related_name="feature_states", |
| 480 | null=True, |
| 481 | on_delete=models.CASCADE, |
| 482 | ) |
| 483 | identity = models.ForeignKey( |
| 484 | "identities.Identity", |
| 485 | related_name="identity_features", |
| 486 | null=True, |
| 487 | default=None, |
| 488 | blank=True, |
| 489 | on_delete=models.CASCADE, |
| 490 | ) |
| 491 | feature_segment = models.ForeignKey( |
| 492 | FeatureSegment, |
| 493 | related_name="feature_states", |
| 494 | null=True, |
| 495 | blank=True, |
| 496 | default=None, |
| 497 | on_delete=models.CASCADE, |
| 498 | ) |
| 499 | |
| 500 | enabled = models.BooleanField(default=False) |
| 501 | |
| 502 | created_at = models.DateTimeField(auto_now_add=True) |
| 503 | updated_at = models.DateTimeField(auto_now=True) |
| 504 | live_from = models.DateTimeField(null=True) |
| 505 | |
| 506 | change_request = models.ForeignKey( |
| 507 | "workflows_core.ChangeRequest", |
| 508 | on_delete=models.CASCADE, |
| 509 | null=True, |
| 510 | related_name="feature_states", |
| 511 | ) |
| 512 | |
| 513 | objects = FeatureStateManager() # type: ignore[misc] |
| 514 | |
| 515 | environment_feature_version = models.ForeignKey( |
| 516 | "feature_versioning.EnvironmentFeatureVersion", |
| 517 | on_delete=models.SET_NULL, |
| 518 | null=True, |
searching dependent graphs…