From 1e9aaf1a828e40a715e49cdd1e9b775a82c26c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20Hermida?= Date: Mon, 4 Jun 2018 13:17:21 +0200 Subject: [PATCH 1/2] Add test_get_user_stories_assigned_users --- tests/integration/test_userstories.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/integration/test_userstories.py b/tests/integration/test_userstories.py index 82979b89..897b6b37 100644 --- a/tests/integration/test_userstories.py +++ b/tests/integration/test_userstories.py @@ -693,6 +693,29 @@ def test_api_filter_by_finish_date(client): assert number_of_userstories == 1 assert response.data[0]["subject"] == userstory_to_finish.subject + +def test_api_filter_by_assigned_users(client): + user = f.UserFactory(is_superuser=True) + user2 = f.UserFactory(is_superuser=True) + + userstory = f.create_userstory(owner=user, subject="test 2 users", + assigned_to=user, + assigned_users=[user.id, user2.id]) + f.create_userstory( + owner=user, subject="test 1 user", assigned_to=user, + assigned_users=[user.id] + ) + + url = reverse("userstories-list") + "?assigned_users=%s" % (user.id) + + client.login(userstory.owner) + response = client.get(url) + number_of_userstories = len(response.data) + + assert response.status_code == 200 + assert number_of_userstories == 2 + + @pytest.mark.parametrize("field_name", ["estimated_start", "estimated_finish"]) def test_api_filter_by_milestone__estimated_start_and_end(client, field_name): user = f.UserFactory(is_superuser=True) From 069a79a174b19ab4b86734e488a12341908a87f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20Hermida?= Date: Mon, 4 Jun 2018 14:36:51 +0200 Subject: [PATCH 2/2] Refactor AssignedUsersFilter --- taiga/base/filters.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/taiga/base/filters.py b/taiga/base/filters.py index f8840111..154a074b 100644 --- a/taiga/base/filters.py +++ b/taiga/base/filters.py @@ -22,7 +22,7 @@ from dateutil.parser import parse as parse_date from django.apps import apps from django.contrib.contenttypes.models import ContentType -from django.db.models import Q +from django.db.models import Q, OuterRef, Subquery from django.utils.translation import ugettext as _ from taiga.base import exceptions as exc @@ -423,24 +423,19 @@ class AssignedToFilter(BaseRelatedFieldsFilter): class AssignedUsersFilter(BaseRelatedFieldsFilter): filter_name = 'assigned_users' - def get_lookup_expression(self, field_name, value): - if None in value: - qs_in_kwargs = { - "{}__in".format(field_name): [v for v in value if - v is not None]} - qs_isnull_kwargs = {"{}__isnull".format(field_name): True} - return Q(**qs_in_kwargs) | Q(**qs_isnull_kwargs) - else: - return Q(**{"{}__in".format(field_name): value}) - def _get_queryparams(self, params): param_name = self.param_name or self.filter_name raw_value = params.get(param_name, None) if raw_value: value = self._prepare_filter_data(raw_value) - assigned_user_filter = self.get_lookup_expression(param_name, value) - assigned_to_filter = self.get_lookup_expression('assigned_to', value) + UserStoryModel = apps.get_model("userstories", "UserStory") + + assigned_users_ids = UserStoryModel.objects.order_by().filter( + assigned_users__in=value, id=OuterRef('pk')).values('pk') + + assigned_user_filter = Q(pk__in=Subquery(assigned_users_ids)) + assigned_to_filter = Q(assigned_to__in=value) return Q(assigned_user_filter | assigned_to_filter)