Commits

k0001 committed 2ea798e

Fix QuerySet filtering on BaseHandler.read()

  • Participants
  • Parent commits e539a10

Comments (0)

Files changed (4)

piston/handler.py

         if not self.has_model():
             return rc.NOT_IMPLEMENTED
 
-        pkfield = self.model._meta.pk.name
+        qs = self.queryset(request).filter(**kwargs)
 
-        if pkfield in kwargs:
+        if 'pk' in kwargs or hasattr(self, 'model') and self.model._meta.pk.name in kwargs:
             try:
-                return self.queryset(request).get(pk=kwargs.get(pkfield))
+                return qs.get()
             except ObjectDoesNotExist:
                 return rc.NOT_FOUND
-            except MultipleObjectsReturned: # should never happen, since we're using a PK
-                return rc.BAD_REQUEST
         else:
-            return self.queryset(request).filter(*args, **kwargs)
+            return qs
 
     def create(self, request, *args, **kwargs):
         if not self.has_model():

tests/test_project/apps/testapp/handlers.py

 from forms import EchoForm
 from test_project.apps.testapp import signals
 
+class DefaultTestModelHandler(BaseHandler):
+    model = TestModel
+
 class EntryHandler(BaseHandler):
     model = TestModel
     allowed_methods = ['GET', 'PUT', 'POST']

tests/test_project/apps/testapp/tests.py

         resp = self.client.post('/api/issue58.json', outgoing, content_type='application/json',
                                 HTTP_AUTHORIZATION=self.auth_string)
         self.assertEquals(resp.status_code, 201)
+
+class ReadFilterTest(MainTests):
+    """Test filtering QuerySets on read()."""
+
+    def init_delegate(self):
+        self.t1_data = TestModel(test1='a', test2='X')
+        self.t1_data.save()
+        self.t2_data = TestModel(test1='b', test2='X')
+        self.t2_data.save()
+
+    def test_unfilter_multi(self):
+        expected = """[\n    {\n        "test1": "a", \n        "test2": "X"\n    }, \n    {\n        "test1": "b", \n        "test2": "X"\n    }\n]"""
+        resp = self.client.get('/api/testmodel/')
+        self.assertEquals(resp.content, expected)
+
+    def test_unfilter_single(self):
+        expected = """{\n    "test1": "a", \n    "test2": "X"\n}"""
+
+        resp = self.client.get('/api/testmodel/by-pk/%d/' % self.t1_data.pk)
+        self.assertEquals(resp.content, expected)
+
+        resp = self.client.get('/api/testmodel/by-id/%d/' % self.t1_data.id)
+        self.assertEquals(resp.content, expected)
+
+        # test1 == 'b'
+        expected = """{\n    "test1": "b", \n    "test2": "X"\n}"""
+
+        resp = self.client.get('/api/testmodel/by-pk/%d/' % self.t2_data.pk)
+        self.assertEquals(resp.content, expected)
+
+        resp = self.client.get('/api/testmodel/by-id/%d/' % self.t2_data.id)
+        self.assertEquals(resp.content, expected)
+
+    def test_filter_multi(self):
+        expected = """[\n    {\n        "test1": "a", \n        "test2": "X"\n    }\n]"""
+
+        resp = self.client.get('/api/testmodel/a/')
+        self.assertEquals(resp.content, expected)
+
+    def test_filter_single(self):
+        expected = """{\n    "test1": "a", \n    "test2": "X"\n}"""
+
+        resp = self.client.get('/api/testmodel/a/by-pk/%d/' % self.t1_data.pk)
+        self.assertEquals(resp.content, expected)
+
+        resp = self.client.get('/api/testmodel/a/by-id/%d/' % self.t1_data.id)
+        self.assertEquals(resp.content, expected)
+
+
+    def test_filter_single_missing(self):
+        # We are filtering test1 == 'a', so this should fail because self.t2.test1 == 'b'. 
+        resp = self.client.get('/api/testmodel/a/by-pk/%d/' % self.t2_data.pk)
+        self.assertEquals(resp.status_code, 404)
+
+        resp = self.client.get('/api/testmodel/a/by-id/%d/' % self.t2_data.id)
+        self.assertEquals(resp.status_code, 404)
+
+

tests/test_project/apps/testapp/urls.py

 from piston.resource import Resource
 from piston.authentication import HttpBasicAuthentication, HttpBasicSimple
 
-from test_project.apps.testapp.handlers import EntryHandler, ExpressiveHandler, AbstractHandler, EchoHandler, PlainOldObjectHandler, Issue58Handler, ListFieldsHandler
+from test_project.apps.testapp.handlers import DefaultTestModelHandler, EntryHandler, ExpressiveHandler, AbstractHandler, EchoHandler, PlainOldObjectHandler, Issue58Handler, ListFieldsHandler
 
 auth = HttpBasicAuthentication(realm='TestApplication')
 
 popo = Resource(handler=PlainOldObjectHandler)
 list_fields = Resource(handler=ListFieldsHandler)
 issue58 = Resource(handler=Issue58Handler)
+default_testmodel = Resource(handler=DefaultTestModelHandler)
 
 AUTHENTICATORS = [auth,]
 SIMPLE_USERS = (('admin', 'secr3t'),
 
     url(r'^multiauth/$', multiauth),
 
+    url(r'^testmodel/$', default_testmodel),
+    url(r'^testmodel/by-pk/(?P<pk>.+)/$', default_testmodel),
+    url(r'^testmodel/by-id/(?P<id>.+)/$', default_testmodel),
+    url(r'^testmodel/a/$', default_testmodel, {'test1': 'a'}),
+    url(r'^testmodel/a/by-pk/(?P<pk>.+)/$', default_testmodel, {'test1': 'a'}),
+    url(r'^testmodel/a/by-id/(?P<id>.+)/$', default_testmodel, {'test1': 'a'}),
+
     # oauth entrypoints
     url(r'^oauth/request_token$', 'piston.authentication.oauth_request_token'),
     url(r'^oauth/authorize$', 'piston.authentication.oauth_user_auth'),