随着NoSQL的广泛使用,mysql这类传统的关系型数据的使用逐渐减少。
django对mysql的REST支持大家应该都很清楚,但是对mongo的支持似乎并不是这么完美,还需要自己添添补补,用起来总是不顺手。
公司刚好有个项目是对mongo数据的增删改查操作,借这个机会我写了一个基类实现mongo的REST,这个类基于django的View(from django.views.generic import View),没有引用其他的库,用起来也很方便,下面简单展示下代码(以下代码不完整,需要下载代码请到github, https://github.com/guozhihua12/mongo-rest):
首先是MongoListView,接受get和post请求,get对应的是list接口,post是create接口。
mongo有一个特点,就是你不知道有哪些列,如果使用动态的documnets的话,所以我们需要把所有的值进行to_mongo().to_dict()操作。还有就是post的时候需要res = self.document(**results),把所有传入的值都保存起来。
class MongoListView(View):
document = None
queryset = None
initial = {}
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
result = []
for row in self.object_list:
value = row.to_mongo().to_dict()
value.pop('_id')
result.append(value)
return JsonResponse(Results().succss_result(result))
def post(self, request, *args, **kwargs):
self.object = None
results = self.get_form_kwargs().get('data').dict()
res = self.document(**results)
res.save()
return HttpResponseRedirect(res.get_absolute_url())
下面是MongoObjectView,为了避免代码的重复,我继承了MongoListView,这个类接受3个请求——get、 post和 delete(分别对应detail, update, delete操作。)重点讲下update操作,由于mongo列的不确定性,我们需要先把之前的数据取出old_results = self.object.to_mongo().to_dict(),然后把传入的数据转化成dict, new_results = self.get_form_kwargs().get(‘data’).dict(),再将old_results和new_results组合成新的dict保存到mongo中。
class MongoObjectView(MongoListView):
document = None
slug_url_kwarg = 'slug'
pk_url_kwarg = 'pk'
slug_field = 'slug'
def get(self, request, **kwargs):
self.object = self.get_object()
result = self.object.to_mongo().to_dict()
result.pop('_id')
return JsonResponse(Results().succss_result(result))
def post(self, request, *args, **kwargs):
self.object = self.get_object()
old_results = self.object.to_mongo().to_dict()
new_results = self.get_form_kwargs().get('data').dict()
results=dict(old_results.items()+new_results.items())
res = self.document(**results)
res.save()
self.object.delete()
return HttpResponseRedirect(res.get_absolute_url())
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.delete()
return JsonResponse(Results().succss_result())