1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
from utils import rc
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
typemapper = { }
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)
if hasattr(new_cls, 'model'):
typemapper[new_cls] = (new_cls.model, new_cls.is_anonymous)
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')
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.model.objects.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)
def create(self, request, *args, **kwargs):
if not self.has_model():
return rc.NOT_IMPLEMENTED
attrs = self.flatten_dict(request.POST)
try:
inst = self.model.objects.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):
# TODO: This doesn't work automatically yet.
return rc.NOT_IMPLEMENTED
def delete(self, request, *args, **kwargs):
if not self.has_model():
raise NotImplementedError
try:
inst = self.model.objects.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',)
|