Commits

Jesper Nøhr  committed 4830140

piston: complete CRUD testcase for repositories, modelform validation, etc.

  • Participants
  • Parent commits abe924e

Comments (0)

Files changed (5)

File piston/emitters.py

             self.data = tuple([m for m in payload.all()])
         elif isinstance(payload, Model):
             self.data = payload
+        elif isinstance(payload, Exception):
+            raise payload
+        elif isinstance(payload, basestring):
+            self.data = str(payload)
         else:
             raise ValueError("Can't emit this.")
     
                     if mf.serialize:
                         if mf.attname in want_fields:
                             ret[mf.name] = _m2m(data, mf)
-
+                            
             else:
 
                 for f in data._meta.fields:

File piston/forms.py

+from django import forms
+
+class Form(forms.Form):
+    pass
+    
+class ModelForm(forms.ModelForm):
+    def merge_from_initial(self):
+        self.data._mutable = True
+        filt = lambda v: v not in self.data.keys()
+        for field in filter(filt, getattr(self.Meta, 'fields', ())):
+            self.data[field] = self.initial.get(field, None)
+

File piston/handler.py

 class BaseHandler(object):
     __metaclass__ = HandlerType
 
+    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
+
     def flatten_dict(self, dct):
         return dict([ (str(k), dct.get(k)) for k in dct.keys() ])
 
     def has_model(self):
         return hasattr(self, 'model')
 
+    def exists(self, **kwa):
+        if not self.has_model():
+            raise NotImplementedError
+            
+        try:
+            self.model.objects.get(**kwa)
+            return True
+        except self.model.DoesNotExist:
+            return False
+
     def read(self, request, *a, **kwa):
         if not self.has_model():
             raise NotImplementedError
         except self.model.DoesNotExist:
             inst = self.model(attrs)
             inst.save()
-
-            return inst        
-                        
+            return inst
+            
     def update(self, request, *a, **kwa):
         if not self.has_model():
             raise NotImplementedError
             
         inst = self.model.objects.get(*a, **kwa)
-        print "must update instance", inst, "with", request.POST
+        print "must update instance", inst, "with", request.PUT
+
+        return "I can't do this yet."
+
+    def delete(self, request, *a, **kwa):
+        if not self.has_model():
+            raise NotImplementedError
+
+        return "I can't do this yet."

File piston/resource.py

 """
 Piston resource.
 """
-from django.http import HttpResponse, Http404
+from django.http import HttpResponse, Http404, HttpResponseNotAllowed, HttpResponseForbidden
 from emitters import Emitter
 from handler import typemapper
+from utils import coerce_put_post, FormValidationError
 
 class NoAuthentication(object):
     def is_authenticated(self, request):
         if not self.authentication.is_authenticated(request):
             return self.authentication.challenge()
 
-        rm = request.method.upper()        
+        rm = request.method.upper()
+        
+        # Django's internal mechanism doesn't pick up
+        # PUT request, so we trick it a little here.
+        if rm == "PUT": coerce_put_post(request)
+
+        if not rm in self.handler.allowed_methods:
+            return HttpResponseNotAllowed(self.handler.allowed_methods)
+
         meth = getattr(self.handler, Resource.callmap.get(rm), None)
         format = request.GET.get('format', 'json')
         
         if not meth:        
             raise Http404
 
-        result = meth(request)
+        try:
+            result = meth(request, *args, **kwargs)
+        except FormValidationError, errors:
+            return HttpResponse("errors: %r" % errors)
+        except Exception, e:
+            result = e
+            
         emitter, ct = Emitter.get(format)
         srl = emitter(result, typemapper)
         

File piston/utils.py

+from django.http import HttpResponseNotAllowed, HttpResponseForbidden
+
+class HttpForbidden(HttpResponseForbidden):
+    pass
+
+class FormValidationError(Exception):
+    pass
+
+def validate(form, operation='POST'):
+    def dec(func):
+        def wrap(self, request, *a, **kwa):
+            f = form(getattr(request, operation))
+
+            if f.is_valid():
+                kwa.update({'form':f})
+                return func(self, request, *a, **kwa)
+            else:
+                raise FormValidationError(f.errors)
+                                
+        return wrap
+    return dec
+
+def coerce_put_post(request):
+    if request.method == "PUT":
+        request.method = "POST"
+        request._load_post_and_files()
+        request.method = "PUT"
+        request.PUT = request.POST
+        del request._post