fromutilsimportrcfromdjango.core.exceptionsimportObjectDoesNotExist,MultipleObjectsReturnedtypemapper={}classHandlerMetaClass(type):""" Metaclass that keeps a registry of class -> handler mappings. """def__new__(cls,name,bases,attrs):new_cls=type.__new__(cls,name,bases,attrs)ifhasattr(new_cls,'model'):typemapper[new_cls]=(new_cls.model,new_cls.is_anonymous)returnnew_clsclassBaseHandler(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__=HandlerMetaClassallowed_methods=('GET','POST','PUT','DELETE')anonymous=is_anonymous=Falseexclude=('id',)fields=()defflatten_dict(self,dct):returndict([(str(k),dct.get(k))forkindct.keys()])defhas_model(self):returnhasattr(self,'model')orhasattr(self,'queryset')defqueryset(self,request):returnself.model.objects.all()defvalue_from_tuple(tu,name):forint_,nintu:ifn==name:returnint_returnNonedefexists(self,**kwargs):ifnotself.has_model():raiseNotImplementedErrortry:self.model.objects.get(**kwargs)returnTrueexceptself.model.DoesNotExist:returnFalsedefread(self,request,*args,**kwargs):ifnotself.has_model():returnrc.NOT_IMPLEMENTEDpkfield=self.model._meta.pk.nameifpkfieldinkwargs:try:returnself.queryset(request).get(pk=kwargs.get(pkfield))exceptObjectDoesNotExist:returnrc.NOT_FOUNDexceptMultipleObjectsReturned:# should never happen, since we're using a PKreturnrc.BAD_REQUESTelse:returnself.queryset(request).filter(*args,**kwargs)defcreate(self,request,*args,**kwargs):ifnotself.has_model():returnrc.NOT_IMPLEMENTEDattrs=self.flatten_dict(request.POST)try:inst=self.queryset(request).get(**attrs)returnrc.DUPLICATE_ENTRYexceptself.model.DoesNotExist:inst=self.model(**attrs)inst.save()returninstexceptself.model.MultipleObjectsReturned:returnrc.DUPLICATE_ENTRYdefupdate(self,request,*args,**kwargs):ifnotself.has_model():returnrc.NOT_IMPLEMENTEDpkfield=self.model._meta.pk.nameifpkfieldnotinkwargs:# No pk was specifiedreturnrc.BAD_REQUESTtry:inst=self.queryset(request).get(pk=kwargs.get(pkfield))exceptObjectDoesNotExist:returnrc.NOT_FOUNDexceptMultipleObjectsReturned:# should never happen, since we're using a PKreturnrc.BAD_REQUESTattrs=self.flatten_dict(request.POST)fork,vinattrs.iteritems():setattr(inst,k,v)inst.save()returnrc.ALL_OKdefdelete(self,request,*args,**kwargs):ifnotself.has_model():raiseNotImplementedErrortry:inst=self.queryset(request).get(*args,**kwargs)inst.delete()returnrc.DELETEDexceptself.model.MultipleObjectsReturned:returnrc.DUPLICATE_ENTRYexceptself.model.DoesNotExist:returnrc.NOT_HEREclassAnonymousBaseHandler(BaseHandler):""" Anonymous handler. """is_anonymous=Trueallowed_methods=('GET',)