[WEB-4544] chore: added field validations in serializer (#7460)
* chore: added field validations in serializer * chore: added enum for roles
This commit is contained in:
parent
27f74206a3
commit
63d025cbf4
3 changed files with 157 additions and 16 deletions
|
|
@ -20,6 +20,7 @@ from plane.db.models import (
|
|||
ProjectMember,
|
||||
State,
|
||||
User,
|
||||
EstimatePoint,
|
||||
)
|
||||
|
||||
from .base import BaseSerializer
|
||||
|
|
@ -112,13 +113,27 @@ class IssueSerializer(BaseSerializer):
|
|||
if (
|
||||
data.get("parent")
|
||||
and not Issue.objects.filter(
|
||||
workspace_id=self.context.get("workspace_id"), pk=data.get("parent").id
|
||||
workspace_id=self.context.get("workspace_id"),
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=data.get("parent").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Parent is not valid issue_id please pass a valid issue_id"
|
||||
)
|
||||
|
||||
if (
|
||||
data.get("estimate_point")
|
||||
and not EstimatePoint.objects.filter(
|
||||
workspace_id=self.context.get("workspace_id"),
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=data.get("estimate_point").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Estimate point is not valid please pass a valid estimate_point_id"
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from lxml import html
|
||||
|
||||
# Django imports
|
||||
from django.utils import timezone
|
||||
|
||||
|
|
@ -16,7 +18,10 @@ from plane.db.models import (
|
|||
DraftIssueLabel,
|
||||
DraftIssueCycle,
|
||||
DraftIssueModule,
|
||||
ProjectMember,
|
||||
EstimatePoint,
|
||||
)
|
||||
from plane.app.permissions import ROLE
|
||||
|
||||
|
||||
class DraftIssueCreateSerializer(BaseSerializer):
|
||||
|
|
@ -57,14 +62,77 @@ class DraftIssueCreateSerializer(BaseSerializer):
|
|||
data["label_ids"] = label_ids if label_ids else []
|
||||
return data
|
||||
|
||||
def validate(self, data):
|
||||
def validate(self, attrs):
|
||||
if (
|
||||
data.get("start_date", None) is not None
|
||||
and data.get("target_date", None) is not None
|
||||
and data.get("start_date", None) > data.get("target_date", None)
|
||||
attrs.get("start_date", None) is not None
|
||||
and attrs.get("target_date", None) is not None
|
||||
and attrs.get("start_date", None) > attrs.get("target_date", None)
|
||||
):
|
||||
raise serializers.ValidationError("Start date cannot exceed target date")
|
||||
return data
|
||||
|
||||
try:
|
||||
if attrs.get("description_html", None) is not None:
|
||||
parsed = html.fromstring(attrs["description_html"])
|
||||
parsed_str = html.tostring(parsed, encoding="unicode")
|
||||
attrs["description_html"] = parsed_str
|
||||
|
||||
except Exception:
|
||||
raise serializers.ValidationError("Invalid HTML passed")
|
||||
|
||||
# Validate assignees are from project
|
||||
if attrs.get("assignee_ids", []):
|
||||
attrs["assignee_ids"] = ProjectMember.objects.filter(
|
||||
project_id=self.context["project_id"],
|
||||
role__gte=ROLE.MEMBER.value,
|
||||
is_active=True,
|
||||
member_id__in=attrs["assignee_ids"],
|
||||
).values_list("member_id", flat=True)
|
||||
|
||||
# Validate labels are from project
|
||||
if attrs.get("label_ids"):
|
||||
label_ids = [label.id for label in attrs["label_ids"]]
|
||||
attrs["label_ids"] = list(
|
||||
Label.objects.filter(
|
||||
project_id=self.context.get("project_id"), id__in=label_ids
|
||||
).values_list("id", flat=True)
|
||||
)
|
||||
|
||||
# # Check state is from the project only else raise validation error
|
||||
if (
|
||||
attrs.get("state")
|
||||
and not State.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("state").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"State is not valid please pass a valid state_id"
|
||||
)
|
||||
|
||||
# # Check parent issue is from workspace as it can be cross workspace
|
||||
if (
|
||||
attrs.get("parent")
|
||||
and not Issue.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("parent").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Parent is not valid issue_id please pass a valid issue_id"
|
||||
)
|
||||
|
||||
if (
|
||||
attrs.get("estimate_point")
|
||||
and not EstimatePoint.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("estimate_point").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Estimate point is not valid please pass a valid estimate_point_id"
|
||||
)
|
||||
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data):
|
||||
assignees = validated_data.pop("assignee_ids", None)
|
||||
|
|
@ -89,14 +157,14 @@ class DraftIssueCreateSerializer(BaseSerializer):
|
|||
DraftIssueAssignee.objects.bulk_create(
|
||||
[
|
||||
DraftIssueAssignee(
|
||||
assignee=user,
|
||||
assignee_id=assignee_id,
|
||||
draft_issue=issue,
|
||||
workspace_id=workspace_id,
|
||||
project_id=project_id,
|
||||
created_by_id=created_by_id,
|
||||
updated_by_id=updated_by_id,
|
||||
)
|
||||
for user in assignees
|
||||
for assignee_id in assignees
|
||||
],
|
||||
batch_size=10,
|
||||
)
|
||||
|
|
@ -105,14 +173,14 @@ class DraftIssueCreateSerializer(BaseSerializer):
|
|||
DraftIssueLabel.objects.bulk_create(
|
||||
[
|
||||
DraftIssueLabel(
|
||||
label=label,
|
||||
label_id=label_id,
|
||||
draft_issue=issue,
|
||||
project_id=project_id,
|
||||
workspace_id=workspace_id,
|
||||
created_by_id=created_by_id,
|
||||
updated_by_id=updated_by_id,
|
||||
)
|
||||
for label in labels
|
||||
for label_id in labels
|
||||
],
|
||||
batch_size=10,
|
||||
)
|
||||
|
|
@ -163,14 +231,14 @@ class DraftIssueCreateSerializer(BaseSerializer):
|
|||
DraftIssueAssignee.objects.bulk_create(
|
||||
[
|
||||
DraftIssueAssignee(
|
||||
assignee=user,
|
||||
assignee_id=assignee_id,
|
||||
draft_issue=instance,
|
||||
workspace_id=workspace_id,
|
||||
project_id=project_id,
|
||||
created_by_id=created_by_id,
|
||||
updated_by_id=updated_by_id,
|
||||
)
|
||||
for user in assignees
|
||||
for assignee_id in assignees
|
||||
],
|
||||
batch_size=10,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from lxml import html
|
||||
|
||||
# Django imports
|
||||
from django.utils import timezone
|
||||
from django.core.validators import URLValidator
|
||||
|
|
@ -37,6 +39,7 @@ from plane.db.models import (
|
|||
IssueVersion,
|
||||
IssueDescriptionVersion,
|
||||
ProjectMember,
|
||||
EstimatePoint,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -119,6 +122,16 @@ class IssueCreateSerializer(BaseSerializer):
|
|||
):
|
||||
raise serializers.ValidationError("Start date cannot exceed target date")
|
||||
|
||||
try:
|
||||
if attrs.get("description_html", None) is not None:
|
||||
parsed = html.fromstring(attrs["description_html"])
|
||||
parsed_str = html.tostring(parsed, encoding="unicode")
|
||||
attrs["description_html"] = parsed_str
|
||||
|
||||
except Exception:
|
||||
raise serializers.ValidationError("Invalid HTML passed")
|
||||
|
||||
# Validate assignees are from project
|
||||
if attrs.get("assignee_ids", []):
|
||||
attrs["assignee_ids"] = ProjectMember.objects.filter(
|
||||
project_id=self.context["project_id"],
|
||||
|
|
@ -127,6 +140,51 @@ class IssueCreateSerializer(BaseSerializer):
|
|||
member_id__in=attrs["assignee_ids"],
|
||||
).values_list("member_id", flat=True)
|
||||
|
||||
# Validate labels are from project
|
||||
if attrs.get("label_ids"):
|
||||
label_ids = [label.id for label in attrs["label_ids"]]
|
||||
attrs["label_ids"] = list(
|
||||
Label.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
id__in=label_ids,
|
||||
).values_list("id", flat=True)
|
||||
)
|
||||
|
||||
# Check state is from the project only else raise validation error
|
||||
if (
|
||||
attrs.get("state")
|
||||
and not State.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("state").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"State is not valid please pass a valid state_id"
|
||||
)
|
||||
|
||||
# Check parent issue is from workspace as it can be cross workspace
|
||||
if (
|
||||
attrs.get("parent")
|
||||
and not Issue.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("parent").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Parent is not valid issue_id please pass a valid issue_id"
|
||||
)
|
||||
|
||||
if (
|
||||
attrs.get("estimate_point")
|
||||
and not EstimatePoint.objects.filter(
|
||||
project_id=self.context.get("project_id"),
|
||||
pk=attrs.get("estimate_point").id,
|
||||
).exists()
|
||||
):
|
||||
raise serializers.ValidationError(
|
||||
"Estimate point is not valid please pass a valid estimate_point_id"
|
||||
)
|
||||
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data):
|
||||
|
|
@ -190,14 +248,14 @@ class IssueCreateSerializer(BaseSerializer):
|
|||
IssueLabel.objects.bulk_create(
|
||||
[
|
||||
IssueLabel(
|
||||
label=label,
|
||||
label_id=label_id,
|
||||
issue=issue,
|
||||
project_id=project_id,
|
||||
workspace_id=workspace_id,
|
||||
created_by_id=created_by_id,
|
||||
updated_by_id=updated_by_id,
|
||||
)
|
||||
for label in labels
|
||||
for label_id in labels
|
||||
],
|
||||
batch_size=10,
|
||||
)
|
||||
|
|
@ -243,14 +301,14 @@ class IssueCreateSerializer(BaseSerializer):
|
|||
IssueLabel.objects.bulk_create(
|
||||
[
|
||||
IssueLabel(
|
||||
label=label,
|
||||
label_id=label_id,
|
||||
issue=instance,
|
||||
project_id=project_id,
|
||||
workspace_id=workspace_id,
|
||||
created_by_id=created_by_id,
|
||||
updated_by_id=updated_by_id,
|
||||
)
|
||||
for label in labels
|
||||
for label_id in labels
|
||||
],
|
||||
batch_size=10,
|
||||
ignore_conflicts=True,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue