Joshua Ginsberg avatar Joshua Ginsberg committed 43f41a4

Fixes #188 - bind request.FILES to form in @validate decorator

Comments (0)

Files changed (5)

 def validate(v_form, operation='POST'):
     @decorator
     def wrap(f, self, request, *a, **kwa):
-        form = v_form(getattr(request, operation))
+        form = v_form(getattr(request, operation), request.FILES)
     
         if form.is_valid():
             setattr(request, 'form', form)

tests/test_project/apps/testapp/forms.py

 class EchoForm(forms.Form):
     msg = forms.CharField(max_length=128)
 
+class FormWithFileField(forms.Form):
+    chaff = forms.CharField(max_length=50)
+    le_file = forms.FileField()

tests/test_project/apps/testapp/handlers.py

 from piston.utils import rc, validate
 
 from models import TestModel, ExpressiveTestModel, Comment, InheritedModel, PlainOldObject, Issue58Model, ListFieldsModel
-from forms import EchoForm
+from forms import EchoForm, FormWithFileField
 from test_project.apps.testapp import signals
 
 class EntryHandler(BaseHandler):
             return rc.CREATED
         else:
             super(Issue58Model, self).create(request)
+
+class FileUploadHandler(BaseHandler):
+    allowed_methods = ('POST',)
+    
+    @validate(FormWithFileField)
+    def create(self, request):
+        return {'chaff': request.form.cleaned_data['chaff'],
+                'file_size': request.form.cleaned_data['le_file'].size}

tests/test_project/apps/testapp/tests.py

 from django.test import TestCase
+from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
 from django.utils import simplejson
 from django.conf import settings
     print "Can't run YAML testsuite"
     yaml = None
 
-import urllib, base64
+import urllib, base64, tempfile
 
 from test_project.apps.testapp.models import TestModel, ExpressiveTestModel, Comment, InheritedModel, Issue58Model, ListFieldsModel
 from test_project.apps.testapp import signals
         resp = self.client.post('/api/issue58.json', outgoing, content_type='application/json',
                                 HTTP_AUTHORIZATION=self.auth_string)
         self.assertEquals(resp.status_code, 201)
+
+class Issue188ValidateWithFiles(MainTests):
+    def test_whoops_no_file_upload(self):
+        resp = self.client.post(
+            reverse('file-upload-test'),
+            data={'chaff': 'pewpewpew'})
+        self.assertEquals(resp.status_code, 400)
+    
+    def test_upload_with_file(self):
+        tmp_fs = tempfile.NamedTemporaryFile(suffix='.txt')
+        content = 'le_content'
+        tmp_fs.write(content)
+        tmp_fs.seek(0)
+        resp = self.client.post(
+            reverse('file-upload-test'),
+            data={'chaff': 'pewpewpew',
+                  'le_file': tmp_fs})
+        self.assertEquals(resp.status_code, 200)
+        self.assertEquals(simplejson.loads(resp.content),
+                          {'chaff': 'pewpewpew',
+                           'file_size': len(content)})
+
+                    

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 EntryHandler, ExpressiveHandler, AbstractHandler, EchoHandler, PlainOldObjectHandler, Issue58Handler, ListFieldsHandler, FileUploadHandler
 
 auth = HttpBasicAuthentication(realm='TestApplication')
 
 popo = Resource(handler=PlainOldObjectHandler)
 list_fields = Resource(handler=ListFieldsHandler)
 issue58 = Resource(handler=Issue58Handler)
+fileupload = Resource(handler=FileUploadHandler)
 
 AUTHENTICATORS = [auth,]
 SIMPLE_USERS = (('admin', 'secr3t'),
 multiauth = Resource(handler=PlainOldObjectHandler, 
                         authentication=AUTHENTICATORS)
 
-urlpatterns = patterns('',
+urlpatterns = patterns(
+    '',
     url(r'^entries/$', entries),
     url(r'^entries/(?P<pk>.+)/$', entries),
     url(r'^entries\.(?P<emitter_format>.+)', entries),
     url(r'^abstract/(?P<id_>\d+)\.(?P<emitter_format>.+)$', abstract),
 
     url(r'^echo$', echo),
+    
+    url(r'^file_upload/$', fileupload, name='file-upload-test'),
 
     url(r'^multiauth/$', multiauth),
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.