Fix validation of fields in partial updates

For some reason validation of fields in partial updates wasn't
triggered. Investigating I found that in the case of partial updates
every field is marked as not-required when constructing the serializer:

rest_framework/fields.py:173
        if self.partial:
            self.required = False

but I couldn't a find where the place (if such a place exists) where the
fields that came in the PATCH request are marked as required again in
order to trigger their validation.

Basically this hotfix does that, mark as required every field present in
the PATCH request so their validation is performed.
remotes/origin/enhancement/email-actions
Anler Hp 2014-08-07 16:30:34 +02:00
parent 47a28cc3dc
commit 3428a0bd01
2 changed files with 24 additions and 15 deletions

View File

@ -118,3 +118,12 @@ class Serializer(serializers.Serializer):
self._errors['non_field_errors'] = err.messages self._errors['non_field_errors'] = err.messages
return attrs return attrs
class ModelSerializer(serializers.ModelSerializer):
def perform_validation(self, attrs):
for attr in attrs:
field = self.fields.get(attr, None)
if field:
field.required = True
return super().perform_validation(attrs)

View File

@ -18,7 +18,7 @@ from os import path
from rest_framework import serializers from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from taiga.base.serializers import JsonField, PgArrayField from taiga.base.serializers import JsonField, PgArrayField, ModelSerializer
from taiga.users.models import Role, User from taiga.users.models import Role, User
from taiga.users.services import get_photo_or_gravatar_url from taiga.users.services import get_photo_or_gravatar_url
from taiga.users.serializers import UserSerializer from taiga.users.serializers import UserSerializer
@ -32,12 +32,12 @@ from . validators import ProjectExistsValidator
# User Stories common serializers # User Stories common serializers
class PointsSerializer(serializers.ModelSerializer): class PointsSerializer(ModelSerializer):
class Meta: class Meta:
model = models.Points model = models.Points
class UserStoryStatusSerializer(serializers.ModelSerializer): class UserStoryStatusSerializer(ModelSerializer):
class Meta: class Meta:
model = models.UserStoryStatus model = models.UserStoryStatus
@ -61,36 +61,36 @@ class UserStoryStatusSerializer(serializers.ModelSerializer):
# Task common serializers # Task common serializers
class TaskStatusSerializer(serializers.ModelSerializer): class TaskStatusSerializer(ModelSerializer):
class Meta: class Meta:
model = models.TaskStatus model = models.TaskStatus
# Issues common serializers # Issues common serializers
class SeveritySerializer(serializers.ModelSerializer): class SeveritySerializer(ModelSerializer):
class Meta: class Meta:
model = models.Severity model = models.Severity
class PrioritySerializer(serializers.ModelSerializer): class PrioritySerializer(ModelSerializer):
class Meta: class Meta:
model = models.Priority model = models.Priority
class IssueStatusSerializer(serializers.ModelSerializer): class IssueStatusSerializer(ModelSerializer):
class Meta: class Meta:
model = models.IssueStatus model = models.IssueStatus
class IssueTypeSerializer(serializers.ModelSerializer): class IssueTypeSerializer(ModelSerializer):
class Meta: class Meta:
model = models.IssueType model = models.IssueType
# Projects # Projects
class MembershipSerializer(serializers.ModelSerializer): class MembershipSerializer(ModelSerializer):
role_name = serializers.CharField(source='role.name', required=False, read_only=True) role_name = serializers.CharField(source='role.name', required=False, read_only=True)
full_name = serializers.CharField(source='user.get_full_name', required=False, read_only=True) full_name = serializers.CharField(source='user.get_full_name', required=False, read_only=True)
color = serializers.CharField(source='user.color', required=False, read_only=True) color = serializers.CharField(source='user.color', required=False, read_only=True)
@ -121,7 +121,7 @@ class MembershipSerializer(serializers.ModelSerializer):
return UserSerializer(queryset).data return UserSerializer(queryset).data
class ProjectMembershipSerializer(serializers.ModelSerializer): class ProjectMembershipSerializer(ModelSerializer):
role_name = serializers.CharField(source='role.name', required=False) role_name = serializers.CharField(source='role.name', required=False)
full_name = serializers.CharField(source='user.get_full_name', required=False) full_name = serializers.CharField(source='user.get_full_name', required=False)
color = serializers.CharField(source='user.color', required=False) color = serializers.CharField(source='user.color', required=False)
@ -134,7 +134,7 @@ class ProjectMembershipSerializer(serializers.ModelSerializer):
return get_photo_or_gravatar_url(project.user) return get_photo_or_gravatar_url(project.user)
class ProjectSerializer(serializers.ModelSerializer): class ProjectSerializer(ModelSerializer):
tags = PgArrayField(required=False) tags = PgArrayField(required=False)
anon_permissions = PgArrayField(required=False) anon_permissions = PgArrayField(required=False)
public_permissions = PgArrayField(required=False) public_permissions = PgArrayField(required=False)
@ -182,13 +182,13 @@ class ProjectDetailSerializer(ProjectSerializer):
return serializer.data return serializer.data
class ProjectRoleSerializer(serializers.ModelSerializer): class ProjectRoleSerializer(ModelSerializer):
class Meta: class Meta:
model = Role model = Role
fields = ('id', 'name', 'slug', 'order', 'computable') fields = ('id', 'name', 'slug', 'order', 'computable')
class RoleSerializer(serializers.ModelSerializer): class RoleSerializer(ModelSerializer):
members_count = serializers.SerializerMethodField("get_members_count") members_count = serializers.SerializerMethodField("get_members_count")
permissions = PgArrayField(required=False) permissions = PgArrayField(required=False)
@ -200,7 +200,7 @@ class RoleSerializer(serializers.ModelSerializer):
return obj.memberships.count() return obj.memberships.count()
class ProjectTemplateSerializer(serializers.ModelSerializer): class ProjectTemplateSerializer(ModelSerializer):
default_options = JsonField(required=False, label=_("Default options")) default_options = JsonField(required=False, label=_("Default options"))
us_statuses = JsonField(required=False, label=_("User story's statuses")) us_statuses = JsonField(required=False, label=_("User story's statuses"))
points = JsonField(required=False, label=_("Points")) points = JsonField(required=False, label=_("Points"))
@ -215,7 +215,7 @@ class ProjectTemplateSerializer(serializers.ModelSerializer):
model = models.ProjectTemplate model = models.ProjectTemplate
class StarredSerializer(serializers.ModelSerializer): class StarredSerializer(ModelSerializer):
class Meta: class Meta:
model = models.Project model = models.Project
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']