Commits

James Emerton committed 7b3bf59 Merge

Automated merge with file:///Users/james/dev/piston/canonical

Comments (0)

Files changed (5)

piston/handler.py

         return dict([ (str(k), dct.get(k)) for k in dct.keys() ])
     
     def has_model(self):
-        return hasattr(self, 'model')
+        return hasattr(self, 'model') or hasattr(self, 'queryset')
+
+    def queryset(self, request):
+        return self.model.objects.all()
     
     def value_from_tuple(tu, name):
         for int_, n in tu:
 
         if pkfield in kwargs:
             try:
-                return self.model.objects.get(pk=kwargs.get(pkfield))
+                return self.queryset(request).get(pk=kwargs.get(pkfield))
             except ObjectDoesNotExist:
                 return rc.NOT_FOUND
             except MultipleObjectsReturned: # should never happen, since we're using a PK
                 return rc.BAD_REQUEST
         else:
-            return self.model.objects.filter(*args, **kwargs)
+            return self.queryset(request).filter(*args, **kwargs)
     
     def create(self, request, *args, **kwargs):
         if not self.has_model():
         attrs = self.flatten_dict(request.POST)
         
         try:
-            inst = self.model.objects.get(**attrs)
+            inst = self.queryset(request).get(**attrs)
             return rc.DUPLICATE_ENTRY
         except self.model.DoesNotExist:
             inst = self.model(**attrs)
             return rc.DUPLICATE_ENTRY
     
     def update(self, request, *args, **kwargs):
-        # TODO: This doesn't work automatically yet.
-        return rc.NOT_IMPLEMENTED
+        if not self.has_model():
+            return rc.NOT_IMPLEMENTED
+
+        pkfield = self.model._meta.pk.name
+
+        if pkfield not in kwargs:
+            # No pk was specified
+            return rc.BAD_REQUEST
+
+        try:
+            inst = self.queryset(request).get(pk=kwargs.get(pkfield))
+        except ObjectDoesNotExist:
+            return rc.NOT_FOUND
+        except MultipleObjectsReturned: # should never happen, since we're using a PK
+            return rc.BAD_REQUEST
+
+        attrs = self.flatten_dict(request.POST)
+        for k,v in attrs.iteritems():
+            setattr( inst, k, v )
+
+        inst.save()
+        return rc.ALL_OK
     
     def delete(self, request, *args, **kwargs):
         if not self.has_model():
             raise NotImplementedError
 
         try:
-            inst = self.model.objects.get(*args, **kwargs)
+            inst = self.queryset(request).get(*args, **kwargs)
 
             inst.delete()
 

piston/managers.py

 from django.db import models
 from django.contrib.auth.models import User
 
-KEY_SIZE = 16
-SECRET_SIZE = 16
+KEY_SIZE = 18
+SECRET_SIZE = 32
 
-class ConsumerManager(models.Manager):
+class KeyManager(models.Manager):
+    '''Add support for random key/secret generation
+    '''
+    def generate_random_codes(self):
+        key = User.objects.make_random_password(length=KEY_SIZE)
+        secret = User.objects.make_random_password(length=SECRET_SIZE)
+
+        while self.filter(key__exact=key, secret__exact=secret).count():
+            secret = User.objects.make_random_password(length=SECRET_SIZE)
+
+        return key, secret
+
+
+class ConsumerManager(KeyManager):
     def create_consumer(self, name, description=None, user=None):
         """
         Shortcut to create a consumer with random key/secret.
             consumer.description = description
 
         if created:
-            consumer.generate_random_codes()
+            consumer.key, consumer.secret = self.generate_random_codes()
+            consumer.save()
 
         return consumer
-    
+
     _default_consumer = None
 
 class ResourceManager(models.Manager):
 
         return self._default_resource        
 
-class TokenManager(models.Manager):
+class TokenManager(KeyManager):
     def create_token(self, consumer, token_type, timestamp, user=None):
         """
         Shortcut to create a token with random key/secret.
                                             user=user)
 
         if created:
-            token.generate_random_codes()
+            token.key, token.secret = self.generate_random_codes()
+            token.save()
 
-        return token
+        return token
+        
 from django.core.mail import send_mail, mail_admins
 from django.template import loader
 
-from managers import TokenManager, ConsumerManager, ResourceManager
-
-KEY_SIZE = 18
-SECRET_SIZE = 32
+from managers import TokenManager, ConsumerManager, ResourceManager, KEY_SIZE, SECRET_SIZE
 
 CONSUMER_STATES = (
     ('pending', 'Pending approval'),
     def __unicode__(self):
         return u"Consumer %s with key %s" % (self.name, self.key)
 
-    def generate_random_codes(self):
-        key = User.objects.make_random_password(length=KEY_SIZE)
-
-        secret = User.objects.make_random_password(length=SECRET_SIZE)
-
-        while Consumer.objects.filter(key__exact=key, secret__exact=secret).count():
-            secret = User.objects.make_random_password(length=SECRET_SIZE)
-
-        self.key = key
-        self.secret = secret
-        self.save()
-
-    # -- 
-    
     def save(self, **kwargs):
         super(Consumer, self).save(**kwargs)
         
             del token_dict['oauth_token_secret']
         return urllib.urlencode(token_dict)
 
-    def generate_random_codes(self):
-        key = User.objects.make_random_password(length=KEY_SIZE)
-        secret = User.objects.make_random_password(length=SECRET_SIZE)
-
-        while Token.objects.filter(key__exact=key, secret__exact=secret).count():
-            secret = User.objects.make_random_password(length=SECRET_SIZE)
-
-        self.key = key
-        self.secret = secret
-        self.save()
-        
-admin.site.register(Token)
+admin.site.register(Token)

piston/resource.py

 from django.views.decorators.vary import vary_on_headers
 from django.conf import settings
 from django.core.mail import send_mail, EmailMessage
+from django.db.models.query import QuerySet
 
 from emitters import Emitter
 from handler import typemapper
                 raise
 
         emitter, ct = Emitter.get(em_format)
-        srl = emitter(result, typemapper, handler, handler.fields, anonymous)
+        fields = handler.fields
+        if hasattr(handler, 'list_fields') and (
+                isinstance(result, list) or isinstance(result, QuerySet)):
+            fields = handler.list_fields
+
+        srl = emitter(result, typemapper, handler, fields, anonymous)
 
         try:
             """

tests/test_project/apps/testapp/tests.py

     def setUp(self):
         super(OAuthTests, self).setUp()
 
-        self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted')
-        self.consumer.generate_random_codes()
+        self.consumer = Consumer.objects.create_consumer('Test Consumer')
+        self.consumer.status = 'accepted'
         self.consumer.save()
 
     def tearDown(self):
         resp = self.client.get('/api/popo')
         self.assertEquals(resp.status_code, 200)
         self.assertEquals({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content))
+