[PATCH 4/4] REST: Allow filtering of users by usernames

Stephen Finucane stephen at that.guru
Mon Dec 11 04:30:35 AEDT 2017


Signed-off-by: Stephen Finucane <stephen at that.guru>
---
 patchwork/api/filters.py                             | 19 +++++++++++++++++++
 patchwork/tests/test_rest_api.py                     | 20 +++++++++++++++++++-
 patchwork/tests/utils.py                             |  4 +++-
 .../improved-rest-filtering-bf68399270a9b245.yaml    |  7 +++++++
 4 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py
index c34f5496..85a74afc 100644
--- a/patchwork/api/filters.py
+++ b/patchwork/api/filters.py
@@ -17,6 +17,7 @@
 # along with Patchwork; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django_filters import FilterSet
 from django_filters import IsoDateTimeFilter
@@ -149,8 +150,24 @@ class PatchFilter(ProjectMixin, TimestampMixin, FilterSet):
                   'state', 'archived')
 
 
+class UserChoiceField(ModelMultiChoiceField):
+
+    def _get_filters(self, value):
+        try:
+            return {'pk': int(value)}
+        except ValueError:
+            return {'username__iexact': value}
+
+
+class UserFilter(ModelChoiceFilter):
+
+    field_class = UserChoiceField
+
+
 class CheckFilter(TimestampMixin, FilterSet):
 
+    user = UserFilter(queryset=User.objects.all())
+
     class Meta:
         model = Check
         fields = ('user', 'state', 'context')
@@ -165,6 +182,8 @@ class EventFilter(ProjectMixin, TimestampMixin, FilterSet):
 
 class BundleFilter(ProjectMixin, FilterSet):
 
+    owner = UserFilter(queryset=User.objects.all())
+
     class Meta:
         model = Bundle
         fields = ('project', 'owner', 'public')
diff --git a/patchwork/tests/test_rest_api.py b/patchwork/tests/test_rest_api.py
index 7d10f909..3e264e15 100644
--- a/patchwork/tests/test_rest_api.py
+++ b/patchwork/tests/test_rest_api.py
@@ -708,6 +708,14 @@ class TestCheckAPI(APITestCase):
         self.assertEqual(1, len(resp.data))
         self.assertSerialized(check_obj, resp.data[0])
 
+        # test filtering by owner, both ID and username
+        resp = self.client.get(self.api_url(), {'user': self.user.id})
+        self.assertEqual([check_obj.id], [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'user': self.user.username})
+        self.assertEqual([check_obj.id], [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'user': 'otheruser'})
+        self.assertEqual(0, len(resp.data))
+
     def test_detail(self):
         """Validate we can get a specific check."""
         check = self._create_check()
@@ -794,7 +802,7 @@ class TestBundleAPI(APITestCase):
         self.assertEqual(status.HTTP_200_OK, resp.status_code)
         self.assertEqual(0, len(resp.data))
 
-        user = create_user()
+        user = create_user(username='myuser')
         project = create_project(linkname='myproject')
         bundle_public = create_bundle(public=True, owner=user,
                                       project=project)
@@ -826,6 +834,16 @@ class TestBundleAPI(APITestCase):
         resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
         self.assertEqual(0, len(resp.data))
 
+        # test filtering by owner, both ID and username
+        resp = self.client.get(self.api_url(), {'owner': user.id})
+        self.assertEqual([bundle_public.id, bundle_private.id],
+                         [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'owner': 'myuser'})
+        self.assertEqual([bundle_public.id, bundle_private.id],
+                         [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'owner': 'otheruser'})
+        self.assertEqual(0, len(resp.data))
+
     def test_detail(self):
         """Validate we can get a specific bundle."""
         bundle = create_bundle(public=True)
diff --git a/patchwork/tests/utils.py b/patchwork/tests/utils.py
index d4005c77..004c2ca0 100644
--- a/patchwork/tests/utils.py
+++ b/patchwork/tests/utils.py
@@ -101,15 +101,17 @@ def create_user(link_person=True, **kwargs):
     num = User.objects.count()
 
     values = {
+        'username': 'test_user_%d' % num,
         'name': 'test_user_%d' % num,
         'email': 'test_user_%d at example.com' % num,
     }
     values.update(kwargs)
 
-    user = User.objects.create_user(values['name'], values['email'],
+    user = User.objects.create_user(values['username'], values['email'],
                                     values['name'])
 
     if link_person:
+        values.pop('username')
         create_person(user=user, **values)
 
     return user
diff --git a/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml b/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
index fda68790..b1d12eb6 100644
--- a/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
+++ b/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
@@ -7,3 +7,10 @@ api:
     .. code-block:: shell
 
        $ curl /covers/?submitter=stephen at that.guru
+  - |
+    Bundles can be filtered by owner and checks by user using username. For
+    example:
+
+    .. code-block:: shell
+
+       $ curl /bundles/?owner=stephenfin
-- 
2.14.3



More information about the Patchwork mailing list