+++ /dev/null
-import warnings
-
-from utils import rc
-from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
-from django.conf import settings
-
-typemapper = { }
-handler_tracker = [ ]
-
-class HandlerMetaClass(type):
- """
- Metaclass that keeps a registry of class -> handler
- mappings.
- """
- def __new__(cls, name, bases, attrs):
- new_cls = type.__new__(cls, name, bases, attrs)
-
- def already_registered(model, anon):
- for k, (m, a) in typemapper.iteritems():
- if model == m and anon == a:
- return k
-
- if hasattr(new_cls, 'model'):
- if already_registered(new_cls.model, new_cls.is_anonymous):
- if not getattr(settings, 'PISTON_IGNORE_DUPE_MODELS', False):
- warnings.warn("Handler already registered for model %s, "
- "you may experience inconsistent results." % new_cls.model.__name__)
-
- typemapper[new_cls] = (new_cls.model, new_cls.is_anonymous)
- else:
- typemapper[new_cls] = (None, new_cls.is_anonymous)
-
- if name not in ('BaseHandler', 'AnonymousBaseHandler'):
- handler_tracker.append(new_cls)
-
- return new_cls
-
-class BaseHandler(object):
- """
- Basehandler that gives you CRUD for free.
- You are supposed to subclass this for specific
- functionality.
-
- All CRUD methods (`read`/`update`/`create`/`delete`)
- receive a request as the first argument from the
- resource. Use this for checking `request.user`, etc.
- """
- __metaclass__ = HandlerMetaClass
-
- allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
- anonymous = is_anonymous = False
- exclude = ( 'id', )
- fields = ( )
-
- 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') 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 n == name:
- return int_
- return None
-
- def exists(self, **kwargs):
- if not self.has_model():
- raise NotImplementedError
-
- try:
- self.model.objects.get(**kwargs)
- return True
- except self.model.DoesNotExist:
- return False
-
- def read(self, request, *args, **kwargs):
- if not self.has_model():
- return rc.NOT_IMPLEMENTED
-
- pkfield = self.model._meta.pk.name
-
- if pkfield in kwargs:
- try:
- 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.queryset(request).filter(*args, **kwargs)
-
- def create(self, request, *args, **kwargs):
- if not self.has_model():
- return rc.NOT_IMPLEMENTED
-
- attrs = self.flatten_dict(request.POST)
-
- try:
- inst = self.queryset(request).get(**attrs)
- return rc.DUPLICATE_ENTRY
- except self.model.DoesNotExist:
- inst = self.model(**attrs)
- inst.save()
- return inst
- except self.model.MultipleObjectsReturned:
- return rc.DUPLICATE_ENTRY
-
- def update(self, request, *args, **kwargs):
- 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.queryset(request).get(*args, **kwargs)
-
- inst.delete()
-
- return rc.DELETED
- except self.model.MultipleObjectsReturned:
- return rc.DUPLICATE_ENTRY
- except self.model.DoesNotExist:
- return rc.NOT_HERE
-
-class AnonymousBaseHandler(BaseHandler):
- """
- Anonymous handler.
- """
- is_anonymous = True
- allowed_methods = ('GET',)