diff --git a/taiga/auth/validators.py b/taiga/auth/validators.py
index 6c3661ed..a18dc4bc 100644
--- a/taiga/auth/validators.py
+++ b/taiga/auth/validators.py
@@ -17,11 +17,11 @@
# along with this program. If not, see .
from django.core import validators as core_validators
-from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
+from taiga.base.exceptions import ValidationError
import re
@@ -39,8 +39,8 @@ class BaseRegisterValidator(validators.Validator):
try:
validator(value)
except ValidationError:
- raise serializers.ValidationError(_("Required. 255 characters or fewer. Letters, numbers "
- "and /./-/_ characters'"))
+ raise ValidationError(_("Required. 255 characters or fewer. Letters, numbers "
+ "and /./-/_ characters'"))
return attrs
diff --git a/taiga/base/api/fields.py b/taiga/base/api/fields.py
index 7dfa2c0a..fc4035c2 100644
--- a/taiga/base/api/fields.py
+++ b/taiga/base/api/fields.py
@@ -50,7 +50,6 @@ They are very similar to Django's form fields.
from django import forms
from django.conf import settings
from django.core import validators
-from django.core.exceptions import ValidationError
from django.db.models.fields import BLANK_CHOICE_DASH
from django.forms import widgets
from django.http import QueryDict
@@ -66,6 +65,8 @@ from django.utils.functional import Promise
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
+from taiga.base.exceptions import ValidationError
+
from . import ISO_8601
from .settings import api_settings
diff --git a/taiga/base/api/mixins.py b/taiga/base/api/mixins.py
index 861d77ec..c38b5cb7 100644
--- a/taiga/base/api/mixins.py
+++ b/taiga/base/api/mixins.py
@@ -44,12 +44,12 @@
import warnings
-from django.core.exceptions import ValidationError
from django.http import Http404
from django.db import transaction as tx
from django.utils.translation import ugettext as _
from taiga.base import response
+from taiga.base.exceptions import ValidationError
from .settings import api_settings
from .utils import get_object_or_404
diff --git a/taiga/base/api/relations.py b/taiga/base/api/relations.py
index 60ba9a6e..6fbb98f5 100644
--- a/taiga/base/api/relations.py
+++ b/taiga/base/api/relations.py
@@ -48,7 +48,7 @@ Serializer fields that deal with relationships.
These fields allow you to specify the style that should be used to represent
model relationships, including hyperlinks, primary keys, or slugs.
"""
-from django.core.exceptions import ObjectDoesNotExist, ValidationError
+from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import resolve, get_script_prefix, NoReverseMatch
from django import forms
from django.db.models.fields import BLANK_CHOICE_DASH
@@ -59,6 +59,7 @@ from django.utils.translation import ugettext_lazy as _
from .fields import Field, WritableField, get_component, is_simple_callable
from .reverse import reverse
+from taiga.base.exceptions import ValidationError
import warnings
from urllib import parse as urlparse
diff --git a/taiga/base/api/serializers.py b/taiga/base/api/serializers.py
index 82565b26..f2dfd849 100644
--- a/taiga/base/api/serializers.py
+++ b/taiga/base/api/serializers.py
@@ -78,6 +78,8 @@ import serpy
# This helps keep the separation between model fields, form fields, and
# serializer fields more explicit.
+from taiga.base.exceptions import ValidationError
+
from .relations import *
from .fields import *
diff --git a/taiga/base/exceptions.py b/taiga/base/exceptions.py
index cc58ee6d..73d277ff 100644
--- a/taiga/base/exceptions.py
+++ b/taiga/base/exceptions.py
@@ -51,6 +51,7 @@ In addition Django's built in 403 and 404 exceptions are handled.
"""
from django.core.exceptions import PermissionDenied as DjangoPermissionDenied
+from django.core.exceptions import ValidationError as DjangoValidationError
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.http import Http404
@@ -224,6 +225,7 @@ class NotEnoughSlotsForProject(BaseException):
"total_memberships": total_memberships
}
+
def format_exception(exc):
if isinstance(exc.detail, (dict, list, tuple,)):
detail = exc.detail
@@ -270,3 +272,6 @@ def exception_handler(exc):
# Note: Unhandled exceptions will raise a 500 error.
return None
+
+
+ValidationError = DjangoValidationError
diff --git a/taiga/export_import/serializers/fields.py b/taiga/export_import/serializers/fields.py
index 64c01436..9ed21a19 100644
--- a/taiga/export_import/serializers/fields.py
+++ b/taiga/export_import/serializers/fields.py
@@ -23,11 +23,11 @@ from collections import OrderedDict
from django.core.files.base import ContentFile
from django.core.exceptions import ObjectDoesNotExist
-from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from django.contrib.contenttypes.models import ContentType
from taiga.base.api import serializers
+from taiga.base.exceptions import ValidationError
from taiga.base.fields import JsonField
from taiga.mdrender.service import render as mdrender
from taiga.users import models as users_models
diff --git a/taiga/export_import/serializers/serializers.py b/taiga/export_import/serializers/serializers.py
index 7cf46cba..6a316b68 100644
--- a/taiga/export_import/serializers/serializers.py
+++ b/taiga/export_import/serializers/serializers.py
@@ -16,13 +16,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import copy
-
-from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.fields import JsonField, PgArrayField
+from taiga.base.exceptions import ValidationError
from taiga.projects import models as projects_models
from taiga.projects.custom_attributes import models as custom_attributes_models
@@ -31,15 +29,12 @@ from taiga.projects.tasks import models as tasks_models
from taiga.projects.issues import models as issues_models
from taiga.projects.milestones import models as milestones_models
from taiga.projects.wiki import models as wiki_models
-from taiga.projects.history import models as history_models
-from taiga.projects.attachments import models as attachments_models
from taiga.timeline import models as timeline_models
from taiga.users import models as users_models
from taiga.projects.votes import services as votes_service
-from .fields import (FileField, RelatedNoneSafeField, UserRelatedField,
- UserPkField, CommentField, ProjectRelatedField,
- HistoryUserField, HistoryValuesField, HistoryDiffField,
+from .fields import (FileField, UserRelatedField,
+ ProjectRelatedField,
TimelineDataField, ContentTypeField)
from .mixins import (HistoryExportSerializerMixin,
AttachmentExportSerializerMixin,
@@ -125,7 +120,7 @@ class IssueCustomAttributeExportSerializer(serializers.ModelSerializer):
class BaseCustomAttributesValuesExportSerializer(serializers.ModelSerializer):
- attributes_values = JsonField(source="attributes_values",required=True)
+ attributes_values = JsonField(source="attributes_values", required=True)
_custom_attribute_model = None
_container_field = None
@@ -158,6 +153,7 @@ class BaseCustomAttributesValuesExportSerializer(serializers.ModelSerializer):
return attrs
+
class UserStoryCustomAttributesValuesExportSerializer(BaseCustomAttributesValuesExportSerializer):
_custom_attribute_model = custom_attributes_models.UserStoryCustomAttribute
_container_model = "userstories.UserStory"
@@ -224,7 +220,7 @@ class MilestoneExportSerializer(WatcheableObjectModelSerializerMixin):
name = attrs[source]
qs = self.project.milestones.filter(name=name)
if qs.exists():
- raise serializers.ValidationError(_("Name duplicated for the project"))
+ raise ValidationError(_("Name duplicated for the project"))
return attrs
@@ -268,7 +264,9 @@ class UserStoryExportSerializer(CustomAttributesValuesExportSerializerMixin, His
def custom_attributes_queryset(self, project):
if project.id not in _custom_userstories_attributes_cache:
- _custom_userstories_attributes_cache[project.id] = list(project.userstorycustomattributes.all().values('id', 'name'))
+ _custom_userstories_attributes_cache[project.id] = list(
+ project.userstorycustomattributes.all().values('id', 'name')
+ )
return _custom_userstories_attributes_cache[project.id]
@@ -314,10 +312,10 @@ class WikiLinkExportSerializer(serializers.ModelSerializer):
exclude = ('id', 'project')
-
class TimelineExportSerializer(serializers.ModelSerializer):
data = TimelineDataField()
data_content_type = ContentTypeField()
+
class Meta:
model = timeline_models.Timeline
exclude = ('id', 'project', 'namespace', 'object_id', 'content_type')
diff --git a/taiga/projects/api.py b/taiga/projects/api.py
index c441e419..6445c17f 100644
--- a/taiga/projects/api.py
+++ b/taiga/projects/api.py
@@ -22,7 +22,6 @@ from dateutil.relativedelta import relativedelta
from django.apps import apps
from django.conf import settings
-from django.core.exceptions import ValidationError
from django.http import Http404
from django.utils.translation import ugettext as _
from django.utils import timezone
@@ -651,7 +650,7 @@ class MembershipViewSet(BlockedByProjectMixin, ModelCrudViewSet):
invitation_extra_text=invitation_extra_text,
callback=self.post_save,
precall=self.pre_save)
- except ValidationError as err:
+ except exc.ValidationError as err:
return response.BadRequest(err.message_dict)
members_serialized = self.admin_serializer_class(members, many=True)
diff --git a/taiga/projects/custom_attributes/validators.py b/taiga/projects/custom_attributes/validators.py
index 506c040c..6663de5d 100644
--- a/taiga/projects/custom_attributes/validators.py
+++ b/taiga/projects/custom_attributes/validators.py
@@ -20,7 +20,7 @@
from django.utils.translation import ugettext_lazy as _
from taiga.base.fields import JsonField
-from taiga.base.api.serializers import ValidationError
+from taiga.base.exceptions import ValidationError
from taiga.base.api.validators import ModelValidator
from . import models
diff --git a/taiga/projects/milestones/validators.py b/taiga/projects/milestones/validators.py
index 8de3174c..b7d4d484 100644
--- a/taiga/projects/milestones/validators.py
+++ b/taiga/projects/milestones/validators.py
@@ -18,7 +18,7 @@
from django.utils.translation import ugettext as _
-from taiga.base.api import serializers
+from taiga.base.exceptions import ValidationError
from taiga.base.api import validators
from taiga.projects.validators import DuplicatedNameInProjectValidator
from taiga.projects.notifications.validators import WatchersValidator
@@ -31,7 +31,7 @@ class MilestoneExistsValidator:
value = attrs[source]
if not models.Milestone.objects.filter(pk=value).exists():
msg = _("There's no milestone with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
diff --git a/taiga/projects/notifications/validators.py b/taiga/projects/notifications/validators.py
index 851cc309..40e02083 100644
--- a/taiga/projects/notifications/validators.py
+++ b/taiga/projects/notifications/validators.py
@@ -18,7 +18,7 @@
from django.utils.translation import ugettext as _
-from taiga.base.api import serializers
+from taiga.base.exceptions import ValidationError
class WatchersValidator:
@@ -45,6 +45,6 @@ class WatchersValidator:
existing_watcher_ids = project.get_watchers().values_list("id", flat=True)
result = set(users).difference(member_ids).difference(existing_watcher_ids)
if result:
- raise serializers.ValidationError(_("Watchers contains invalid users"))
+ raise ValidationError(_("Watchers contains invalid users"))
return attrs
diff --git a/taiga/projects/references/validators.py b/taiga/projects/references/validators.py
index 5fcefee8..85456c4c 100644
--- a/taiga/projects/references/validators.py
+++ b/taiga/projects/references/validators.py
@@ -18,6 +18,7 @@
from taiga.base.api import serializers
from taiga.base.api import validators
+from taiga.base.exceptions import ValidationError
class ResolverValidator(validators.Validator):
@@ -32,10 +33,10 @@ class ResolverValidator(validators.Validator):
def validate(self, attrs):
if "ref" in attrs:
if "us" in attrs:
- raise serializers.ValidationError("'us' param is incompatible with 'ref' in the same request")
+ raise ValidationError("'us' param is incompatible with 'ref' in the same request")
if "task" in attrs:
- raise serializers.ValidationError("'task' param is incompatible with 'ref' in the same request")
+ raise ValidationError("'task' param is incompatible with 'ref' in the same request")
if "issue" in attrs:
- raise serializers.ValidationError("'issue' param is incompatible with 'ref' in the same request")
+ raise ValidationError("'issue' param is incompatible with 'ref' in the same request")
return attrs
diff --git a/taiga/projects/tagging/fields.py b/taiga/projects/tagging/fields.py
index 24f92f23..47553d8c 100644
--- a/taiga/projects/tagging/fields.py
+++ b/taiga/projects/tagging/fields.py
@@ -16,11 +16,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from django.core.exceptions import ValidationError
from django.forms import widgets
from django.utils.translation import ugettext_lazy as _
from taiga.base.api import serializers
+from taiga.base.exceptions import ValidationError
import re
diff --git a/taiga/projects/tasks/validators.py b/taiga/projects/tasks/validators.py
index 7f71636c..ddb3f33b 100644
--- a/taiga/projects/tasks/validators.py
+++ b/taiga/projects/tasks/validators.py
@@ -20,6 +20,7 @@ from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
+from taiga.base.exceptions import ValidationError
from taiga.base.fields import PgArrayField
from taiga.projects.milestones.validators import MilestoneExistsValidator
from taiga.projects.notifications.mixins import EditableWatchedResourceSerializer
@@ -34,7 +35,7 @@ class TaskExistsValidator:
value = attrs[source]
if not models.Task.objects.filter(pk=value).exists():
msg = _("There's no task with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
diff --git a/taiga/projects/userstories/validators.py b/taiga/projects/userstories/validators.py
index 4ea0b24a..2d61934f 100644
--- a/taiga/projects/userstories/validators.py
+++ b/taiga/projects/userstories/validators.py
@@ -21,6 +21,7 @@ from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
from taiga.base.api.utils import get_object_or_404
+from taiga.base.exceptions import ValidationError
from taiga.base.fields import PgArrayField
from taiga.base.fields import PickledObjectField
from taiga.projects.milestones.validators import MilestoneExistsValidator
@@ -40,7 +41,7 @@ class UserStoryExistsValidator:
value = attrs[source]
if not models.UserStory.objects.filter(pk=value).exists():
msg = _("There's no user story with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
@@ -105,9 +106,9 @@ class UpdateMilestoneBulkValidator(ProjectExistsValidator, MilestoneExistsValida
project = get_object_or_404(Project, pk=data["project_id"])
if project.user_stories.filter(id__in=user_story_ids).count() != len(user_story_ids):
- raise serializers.ValidationError("all the user stories must be from the same project")
+ raise ValidationError("all the user stories must be from the same project")
if project.milestones.filter(id=data["milestone_id"]).count() != 1:
- raise serializers.ValidationError("the milestone isn't valid for the project")
+ raise ValidationError("the milestone isn't valid for the project")
return data
diff --git a/taiga/projects/validators.py b/taiga/projects/validators.py
index c8ab21bb..de06c05c 100644
--- a/taiga/projects/validators.py
+++ b/taiga/projects/validators.py
@@ -21,6 +21,7 @@ from django.utils.translation import ugettext as _
from taiga.base.api import serializers
from taiga.base.api import validators
+from taiga.base.exceptions import ValidationError
from taiga.base.fields import JsonField
from taiga.base.fields import PgArrayField
from taiga.users.validators import RoleExistsValidator
@@ -49,7 +50,7 @@ class DuplicatedNameInProjectValidator:
qs = model.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
- raise serializers.ValidationError(_("Name duplicated for the project"))
+ raise ValidationError(_("Name duplicated for the project"))
return attrs
@@ -59,7 +60,7 @@ class ProjectExistsValidator:
value = attrs[source]
if not models.Project.objects.filter(pk=value).exists():
msg = _("There's no project with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
@@ -68,7 +69,7 @@ class UserStoryStatusExistsValidator:
value = attrs[source]
if not models.UserStoryStatus.objects.filter(pk=value).exists():
msg = _("There's no user story status with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
@@ -77,7 +78,7 @@ class TaskStatusExistsValidator:
value = attrs[source]
if not models.TaskStatus.objects.filter(pk=value).exists():
msg = _("There's no task status with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
@@ -152,7 +153,7 @@ class MembershipValidator(validators.ModelValidator):
Q(project_id=project.id, email=email))
if qs.count() > 0:
- raise serializers.ValidationError(_("Email address is already taken"))
+ raise ValidationError(_("Email address is already taken"))
return attrs
@@ -164,7 +165,7 @@ class MembershipValidator(validators.ModelValidator):
role = attrs[source]
if project.roles.filter(id=role.id).count() == 0:
- raise serializers.ValidationError(_("Invalid role for the project"))
+ raise ValidationError(_("Invalid role for the project"))
return attrs
@@ -175,10 +176,10 @@ class MembershipValidator(validators.ModelValidator):
if (self.object and self.object.user):
if self.object.user.id == project.owner_id and not attrs[source]:
- raise serializers.ValidationError(_("The project owner must be admin."))
+ raise ValidationError(_("The project owner must be admin."))
if not services.project_has_valid_admins(project, exclude_user=self.object.user):
- raise serializers.ValidationError(
+ raise ValidationError(
_("At least one user must be an active admin for this project.")
)
diff --git a/taiga/users/serializers.py b/taiga/users/serializers.py
index 75daa74e..a28f5ce3 100644
--- a/taiga/users/serializers.py
+++ b/taiga/users/serializers.py
@@ -17,9 +17,6 @@
# along with this program. If not, see .
from django.conf import settings
-from django.core import validators
-from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
from taiga.base.api import serializers
from taiga.base.fields import PgArrayField, Field, MethodField, I18NField
@@ -27,14 +24,11 @@ from taiga.base.fields import PgArrayField, Field, MethodField, I18NField
from taiga.base.utils.thumbnails import get_thumbnail_url
from taiga.projects.models import Project
-from .models import User, Role
from .services import get_photo_or_gravatar_url, get_big_photo_or_gravatar_url
from .gravatar import get_gravatar_url
from collections import namedtuple
-import re
-
######################################################
# User
diff --git a/taiga/users/validators.py b/taiga/users/validators.py
index 11e78efb..f23da47a 100644
--- a/taiga/users/validators.py
+++ b/taiga/users/validators.py
@@ -17,12 +17,12 @@
# along with this program. If not, see .
from django.core import validators as core_validators
-from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from taiga.base.api import serializers
from taiga.base.api import validators
-from taiga.base.fields import PgArrayField, Field
+from taiga.base.exceptions import ValidationError
+from taiga.base.fields import PgArrayField
from .models import User, Role
@@ -34,7 +34,7 @@ class RoleExistsValidator:
value = attrs[source]
if not Role.objects.filter(pk=value).exists():
msg = _("There's no role with that id")
- raise serializers.ValidationError(msg)
+ raise ValidationError(msg)
return attrs
@@ -55,13 +55,13 @@ class UserValidator(validators.ModelValidator):
try:
validator(value)
except ValidationError:
- raise validators.ValidationError(_("Required. 255 characters or fewer. Letters, "
- "numbers and /./-/_ characters'"))
+ raise ValidationError(_("Required. 255 characters or fewer. Letters, "
+ "numbers and /./-/_ characters'"))
if (self.object and
self.object.username != value and
User.objects.filter(username=value).exists()):
- raise validators.ValidationError(_("Invalid username. Try with a different one."))
+ raise ValidationError(_("Invalid username. Try with a different one."))
return attrs
diff --git a/taiga/userstorage/api.py b/taiga/userstorage/api.py
index 5b097e71..94c5ea00 100644
--- a/taiga/userstorage/api.py
+++ b/taiga/userstorage/api.py
@@ -19,7 +19,6 @@
from django.utils.translation import ugettext as _
from taiga.base.api import ModelCrudViewSet
-from taiga.base.api.serializers import ValidationError
from taiga.base import exceptions as exc
from . import models