MCPcopy Create free account
hub / github.com/Flagsmith/flagsmith / MultivariateFeatureOption

Class MultivariateFeatureOption

api/features/multivariate/models.py:33–112  ·  view source on GitHub ↗

This class holds the *value* for a given multivariate feature option. This value is the same for every environment, but the percent allocation is set in MultivariateFeatureStateValue which varies per-environment.

Source from the content-addressed store, hash-verified

31
32
33class MultivariateFeatureOption(
34 LifecycleModelMixin, # type: ignore[misc]
35 AbstractBaseFeatureValueModel,
36 AbstractBaseExportableModel,
37 abstract_base_auditable_model_factory(["uuid"]), # type: ignore[misc]
38):
39 """
40 This class holds the *value* for a given multivariate feature
41 option. This value is the same for every environment, but the
42 percent allocation is set in MultivariateFeatureStateValue
43 which varies per-environment.
44 """
45
46 history_record_class_path = (
47 "features.multivariate.models.HistoricalMultivariateFeatureOption"
48 )
49 related_object_type = RelatedObjectType.FEATURE
50
51 feature = models.ForeignKey(
52 "features.Feature",
53 on_delete=models.CASCADE,
54 related_name="multivariate_options",
55 )
56
57 key = models.CharField(
58 max_length=255,
59 null=True,
60 validators=[validate_slug],
61 help_text="A stable, human-readable identifier for the variant.",
62 )
63
64 # This field is stored at the feature level but not used here - it is transferred
65 # to the MultivariateFeatureStateValue on creation of a new option or when creating
66 # a new environment.
67 default_percentage_allocation = models.FloatField(
68 default=100,
69 validators=[MinValueValidator(0), MaxValueValidator(100)],
70 )
71
72 class Meta:
73 unique_together = ("feature", "key")
74
75 @hook(AFTER_CREATE)
76 def create_multivariate_feature_state_values(self): # type: ignore[no-untyped-def]
77 for feature_state in self.feature.feature_states.filter(
78 identity=None, feature_segment=None
79 ):
80 MultivariateFeatureStateValue.objects.create(
81 feature_state=feature_state,
82 multivariate_feature_option=self,
83 percentage_allocation=self.default_percentage_allocation,
84 )
85
86 @hook(AFTER_CREATE)
87 def make_feature_multivariate(self): # type: ignore[no-untyped-def]
88 # Handle the check on feature.type in the method itself to ensure this is
89 # only performed after create. Using `when` and `is_not` means
90 # LifecycleModel.__init__() queries for feature on every object init.

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…