Fixing and refactoring by_ref api endpoints

remotes/origin/issue/4795/notification_even_they_are_disabled
Alejandro Alonso 2016-10-13 10:48:05 +02:00 committed by David Barragán Merino
parent 7952fb63ee
commit 9d3e53f3c5
6 changed files with 76 additions and 91 deletions

View File

@ -29,6 +29,7 @@ from taiga.base.api.viewsets import NestedViewSetMixin
from taiga.base.utils import json from taiga.base.utils import json
from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.history.mixins import HistoryResourceMixin
from taiga.projects.mixins.by_ref import ByRefMixin
from taiga.projects.models import Project, EpicStatus from taiga.projects.models import Project, EpicStatus
from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin
from taiga.projects.occ import OCCResourceMixin from taiga.projects.occ import OCCResourceMixin
@ -43,9 +44,8 @@ from . import validators
from . import utils as epics_utils from . import utils as epics_utils
class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
WatchedResourceMixin, TaggedResourceMixin, BlockedByProjectMixin, ByRefMixin, TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet):
ModelCrudViewSet):
validator_class = validators.EpicValidator validator_class = validators.EpicValidator
queryset = models.Epic.objects.all() queryset = models.Epic.objects.all()
permission_classes = (permissions.EpicPermission,) permission_classes = (permissions.EpicPermission,)
@ -172,21 +172,6 @@ class EpicViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin,
} }
return response.Ok(services.get_epics_filters_data(project, querysets)) return response.Ok(services.get_epics_filters_data(project, querysets))
@list_route(methods=["GET"])
def by_ref(self, request):
retrieve_kwargs = {
"ref": request.QUERY_PARAMS.get("ref", None)
}
project_id = request.QUERY_PARAMS.get("project", None)
if project_id is not None:
retrieve_kwargs["project_id"] = project_id
project_slug = request.QUERY_PARAMS.get("project__slug", None)
if project_slug is not None:
retrieve_kwargs["project__slug"] = project_slug
return self.retrieve(request, **retrieve_kwargs)
@list_route(methods=["GET"]) @list_route(methods=["GET"])
def csv(self, request): def csv(self, request):
uuid = request.QUERY_PARAMS.get("uuid", None) uuid = request.QUERY_PARAMS.get("uuid", None)

View File

@ -28,6 +28,7 @@ from taiga.base.api.mixins import BlockedByProjectMixin
from taiga.base.api.utils import get_object_or_404 from taiga.base.api.utils import get_object_or_404
from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.history.mixins import HistoryResourceMixin
from taiga.projects.mixins.by_ref import ByRefMixin
from taiga.projects.models import Project, IssueStatus, Severity, Priority, IssueType from taiga.projects.models import Project, IssueStatus, Severity, Priority, IssueType
from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin
from taiga.projects.occ import OCCResourceMixin from taiga.projects.occ import OCCResourceMixin
@ -44,7 +45,7 @@ from . import validators
class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin, class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet): ByRefMixin, TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet):
validator_class = validators.IssueValidator validator_class = validators.IssueValidator
queryset = models.Issue.objects.all() queryset = models.Issue.objects.all()
permission_classes = (permissions.IssuePermission, ) permission_classes = (permissions.IssuePermission, )
@ -174,21 +175,6 @@ class IssueViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, W
super().pre_conditions_on_save(obj) super().pre_conditions_on_save(obj)
@list_route(methods=["GET"])
def by_ref(self, request):
retrieve_kwargs = {
"ref": request.QUERY_PARAMS.get("ref", None)
}
project_id = request.QUERY_PARAMS.get("project", None)
if project_id is not None:
retrieve_kwargs["project_id"] = project_id
project_slug = request.QUERY_PARAMS.get("project__slug", None)
if project_slug is not None:
retrieve_kwargs["project__slug"] = project_slug
return self.retrieve(request, **retrieve_kwargs)
@list_route(methods=["GET"]) @list_route(methods=["GET"])
def filters_data(self, request, *args, **kwargs): def filters_data(self, request, *args, **kwargs):
project_id = request.QUERY_PARAMS.get("project", None) project_id = request.QUERY_PARAMS.get("project", None)

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext as _
from taiga.base import response
from taiga.base.decorators import list_route
class ByRefMixin:
"""
Get an instance by ref.
"""
@list_route(methods=["GET"])
def by_ref(self, request):
if "ref" not in request.QUERY_PARAMS:
return response.BadRequest(_("ref param is needed"))
if "project__slug" not in request.QUERY_PARAMS and "project" not in request.QUERY_PARAMS:
return response.BadRequest(_("project or project__slug param is needed"))
retrieve_kwargs = {
"ref": request.QUERY_PARAMS.get("ref", None)
}
project_id = request.QUERY_PARAMS.get("project", None)
if project_id is not None:
retrieve_kwargs["project_id"] = project_id
project_slug = request.QUERY_PARAMS.get("project__slug", None)
if project_slug is not None:
retrieve_kwargs["project__slug"] = project_slug
return self.retrieve(request, **retrieve_kwargs)

View File

@ -28,6 +28,7 @@ from taiga.base.api.mixins import BlockedByProjectMixin
from taiga.base.utils import json from taiga.base.utils import json
from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.history.mixins import HistoryResourceMixin
from taiga.projects.milestones.models import Milestone from taiga.projects.milestones.models import Milestone
from taiga.projects.mixins.by_ref import ByRefMixin
from taiga.projects.models import Project, TaskStatus from taiga.projects.models import Project, TaskStatus
from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin from taiga.projects.notifications.mixins import WatchedResourceMixin, WatchersViewSetMixin
from taiga.projects.occ import OCCResourceMixin from taiga.projects.occ import OCCResourceMixin
@ -44,9 +45,8 @@ from . import validators
from . import utils as tasks_utils from . import utils as tasks_utils
class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
WatchedResourceMixin, TaggedResourceMixin, BlockedByProjectMixin, ByRefMixin, TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet):
ModelCrudViewSet):
validator_class = validators.TaskValidator validator_class = validators.TaskValidator
queryset = models.Task.objects.all() queryset = models.Task.objects.all()
permission_classes = (permissions.TaskPermission,) permission_classes = (permissions.TaskPermission,)
@ -220,21 +220,6 @@ class TaskViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin,
} }
return response.Ok(services.get_tasks_filters_data(project, querysets)) return response.Ok(services.get_tasks_filters_data(project, querysets))
@list_route(methods=["GET"])
def by_ref(self, request):
retrieve_kwargs = {
"ref": request.QUERY_PARAMS.get("ref", None)
}
project_id = request.QUERY_PARAMS.get("project", None)
if project_id is not None:
retrieve_kwargs["project_id"] = project_id
project_slug = request.QUERY_PARAMS.get("project__slug", None)
if project_slug is not None:
retrieve_kwargs["project__slug"] = project_slug
return self.retrieve(request, **retrieve_kwargs)
@list_route(methods=["GET"]) @list_route(methods=["GET"])
def csv(self, request): def csv(self, request):
uuid = request.QUERY_PARAMS.get("uuid", None) uuid = request.QUERY_PARAMS.get("uuid", None)

View File

@ -36,6 +36,7 @@ from taiga.base.utils import json
from taiga.projects.history.mixins import HistoryResourceMixin from taiga.projects.history.mixins import HistoryResourceMixin
from taiga.projects.history.services import take_snapshot from taiga.projects.history.services import take_snapshot
from taiga.projects.milestones.models import Milestone from taiga.projects.milestones.models import Milestone
from taiga.projects.mixins.by_ref import ByRefMixin
from taiga.projects.models import Project, UserStoryStatus from taiga.projects.models import Project, UserStoryStatus
from taiga.projects.notifications.mixins import WatchedResourceMixin from taiga.projects.notifications.mixins import WatchedResourceMixin
from taiga.projects.notifications.mixins import WatchersViewSetMixin from taiga.projects.notifications.mixins import WatchersViewSetMixin
@ -54,7 +55,7 @@ from . import validators
class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin, class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet): ByRefMixin, TaggedResourceMixin, BlockedByProjectMixin, ModelCrudViewSet):
validator_class = validators.UserStoryValidator validator_class = validators.UserStoryValidator
queryset = models.UserStory.objects.all() queryset = models.UserStory.objects.all()
permission_classes = (permissions.UserStoryPermission,) permission_classes = (permissions.UserStoryPermission,)
@ -295,27 +296,6 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi
} }
return response.Ok(services.get_userstories_filters_data(project, querysets)) return response.Ok(services.get_userstories_filters_data(project, querysets))
@list_route(methods=["GET"])
def by_ref(self, request):
if "ref" not in request.QUERY_PARAMS:
return response.BadRequest(_("ref param is needed"))
if "project_slug" not in request.QUERY_PARAMS and "project" not in request.QUERY_PARAMS:
return response.BadRequest(_("project or project_slug param is needed"))
retrieve_kwargs = {
"ref": request.QUERY_PARAMS["ref"]
}
project_id = request.QUERY_PARAMS.get("project", None)
if project_id is not None:
retrieve_kwargs["project_id"] = project_id
project_slug = request.QUERY_PARAMS.get("project__slug", None)
if project_slug is not None:
retrieve_kwargs["project__slug"] = project_slug
return self.retrieve(request, **retrieve_kwargs)
@list_route(methods=["GET"]) @list_route(methods=["GET"])
def csv(self, request): def csv(self, request):
uuid = request.QUERY_PARAMS.get("uuid", None) uuid = request.QUERY_PARAMS.get("uuid", None)

View File

@ -18,13 +18,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db.models import F from django.db.models import F
from django.db.transaction import atomic from django.db import transaction as tx
from django.apps import apps from django.apps import apps
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from .models import Votes, Vote from .models import Votes, Vote
@tx.atomic
def add_vote(obj, user): def add_vote(obj, user):
"""Add a vote to an object. """Add a vote to an object.
@ -35,7 +37,6 @@ def add_vote(obj, user):
:param user: User adding the vote. :class:`~taiga.users.models.User` instance. :param user: User adding the vote. :class:`~taiga.users.models.User` instance.
""" """
obj_type = apps.get_model("contenttypes", "ContentType").objects.get_for_model(obj) obj_type = apps.get_model("contenttypes", "ContentType").objects.get_for_model(obj)
with atomic():
vote, created = Vote.objects.get_or_create(content_type=obj_type, object_id=obj.id, user=user) vote, created = Vote.objects.get_or_create(content_type=obj_type, object_id=obj.id, user=user)
if not created: if not created:
return return
@ -46,6 +47,7 @@ def add_vote(obj, user):
return vote return vote
@tx.atomic
def remove_vote(obj, user): def remove_vote(obj, user):
"""Remove an user vote from an object. """Remove an user vote from an object.
@ -56,7 +58,6 @@ def remove_vote(obj, user):
:param user: User removing her vote. :class:`~taiga.users.models.User` instance. :param user: User removing her vote. :class:`~taiga.users.models.User` instance.
""" """
obj_type = apps.get_model("contenttypes", "ContentType").objects.get_for_model(obj) obj_type = apps.get_model("contenttypes", "ContentType").objects.get_for_model(obj)
with atomic():
qs = Vote.objects.filter(content_type=obj_type, object_id=obj.id, user=user) qs = Vote.objects.filter(content_type=obj_type, object_id=obj.id, user=user)
if not qs.exists(): if not qs.exists():
return return