[PATCH 4/4] REST: allow to filter series by patch state

Philippe Pepiot philippe.pepiot at logilab.fr
Tue Jul 18 21:55:39 AEST 2017


On 07/16/2017 09:32 PM, Philippe Pepiot wrote:
> In series list API, allow to filter series having at least a patch in
> given state(s).
> 
> Signed-off-by: Philippe Pepiot <phil at philpep.org>
> ---
>  patchwork/api/filters.py         |  4 +++-
>  patchwork/tests/test_rest_api.py | 22 ++++++++++++++++++++++
>  2 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py
> index 7bf574d..a1768f6 100644
> --- a/patchwork/api/filters.py
> +++ b/patchwork/api/filters.py
> @@ -105,9 +105,11 @@ class StateFilter(ModelChoiceFilter):
>  
>  class SeriesFilter(ProjectMixin, TimestampMixin, FilterSet):
>  
> +    patches__state = StateFilter(queryset=State.objects.all())
> +
>      class Meta:
>          model = Series
> -        fields = ('submitter', 'project')
> +        fields = ('submitter', 'project', 'patches__state')


It seems that Series(patches__state__in=[...]) return duplicated rows,
each series appears the number of patches within the series. This is not
visible in tests because each series has exactly one patch.
We should avoid that either with distinct() or SQL EXISTS() in a extra
where clause (the latter seems more efficient).

>  
>  
>  class PatchFilter(ProjectMixin, TimestampMixin, FilterSet):
> diff --git a/patchwork/tests/test_rest_api.py b/patchwork/tests/test_rest_api.py
> index abffd17..f574eb3 100644
> --- a/patchwork/tests/test_rest_api.py
> +++ b/patchwork/tests/test_rest_api.py
> @@ -35,6 +35,7 @@ from patchwork.tests.utils import create_person
>  from patchwork.tests.utils import create_project
>  from patchwork.tests.utils import create_state
>  from patchwork.tests.utils import create_series
> +from patchwork.tests.utils import create_series_patch
>  from patchwork.tests.utils import create_user
>  
>  if settings.ENABLE_REST_API:
> @@ -560,6 +561,27 @@ class TestSeriesAPI(APITestCase):
>          self.assertEqual(1, len(resp.data))
>          self.assertSerialized(series, resp.data[0])
>  
> +    def test_filter(self):
> +        """Validate we can filter series"""
> +        states = [create_state() for _ in range(2)]
> +        series = [create_series() for _ in range(3)]
> +        for patch_series, patch_states in (
> +            (series[0], [states[0]]),
> +            (series[1], [states[1]]),
> +            (series[2], states)
> +        ):
> +            for state in patch_states:
> +                create_series_patch(series=patch_series,
> +                                    patch=create_patch(state=state))
> +
> +        resp = self.client.get(self.api_url())
> +        self.assertEqual([s.pk for s in series],
> +                         [s['id'] for s in resp.data])
> +        resp = self.client.get(self.api_url(),
> +                               {'patches__state': states[0].slug})
> +        self.assertEqual([series[0].pk, series[2].pk],
> +                         [s['id'] for s in resp.data])
> +
>      def test_detail(self):
>          """Validate we can get a specific series."""
>          series = create_series()
> 


More information about the Patchwork mailing list