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