Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions common/segments/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def _update_or_create_segment_rules(
continue

self._update_or_create_conditions(
conditions, child_rule, is_create=is_create
conditions, child_rule, is_create=is_create, segment=segment
)

self._update_or_create_segment_rules(
Expand Down Expand Up @@ -238,6 +238,13 @@ def _update_or_create_segment_rule(
) -> Optional[models.Model]:
SegmentRule = apps.get_model("segments", "SegmentRule")
rule_id = rule_data.pop("id", None)
if rule_id is not None:
segment_rule = SegmentRule.objects.get(id=rule_id)
matching_segment = segment or rule.get_segment()

if segment_rule.get_segment() != matching_segment:
raise ValidationError({"segment": "Mismatched segment is not allowed"})

if rule_data.get("delete"):
SegmentRule.objects.filter(id=rule_id).delete()
return
Expand All @@ -249,16 +256,31 @@ def _update_or_create_segment_rule(

@staticmethod
def _update_or_create_conditions(
conditions_data: dict, rule: models.Model, is_create: bool = False
conditions_data: dict,
rule: models.Model,
segment: models.Model | None = None,
Comment on lines +260 to +261
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clearly out of the scope of this PR, but maybe we should define common abstract models in the flagsmith-common package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be in favour of this.

is_create: bool = False,
) -> None:
Condition = apps.get_model("segments", "Condition")
for condition in conditions_data:
condition_id = condition.pop("id", None)
if condition.get("delete"):
for condition_data in conditions_data:
condition_id = condition_data.pop("id", None)
if condition_id is not None:
condition = Condition.objects.get(id=condition_id)
matching_segment = segment or rule.get_segment()
if condition._get_segment() != matching_segment:
raise ValidationError(
{"segment": "Mismatched segment is not allowed"}
)

if condition_data.get("delete"):
Condition.objects.filter(id=condition_id).delete()
continue

Condition.objects.update_or_create(
id=condition_id,
defaults={**condition, "created_with_segment": is_create, "rule": rule},
defaults={
**condition_data,
"created_with_segment": is_create,
"rule": rule,
},
)
Loading