Python中如何实现一款no-sql风格的Rest API查询框架,支持Django ORM和peewee
RestfulAPI 解析
实现一款 no-sql 风格的参数解析框架rest-query,(like: /?select=id,name,author{id,name,school{*}})&id=gte.20&author.name=wwxiong&order=id.desc)。
目前实现了Django ORM和Peewee ORM
Django DEMO
定义模型
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
age = models.IntegerField()
class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
author = models.ForeignKey(Author)
定义试图
from django.views.generic import ListView
from django.views.generic.detail import DetailView
from django_rest_query import RestQueryDetailViewMixin, RestQueryListViewMixin
from .models import Author, Book
class BookDetail(RestQueryDetailViewMixin, DetailView):
model = Book
class BookList(RestQueryListViewMixin, ListView):
model = Book
class AuthorDetail(RestQueryDetailViewMixin, DetailView):
model = Author
class AuthorList(RestQueryListViewMixin, ListView):
model = Author
这样我们就实现了Author和Book的查询 API 了。
API
查询姓名为dracarysX的作者,并只返回id, name:
curl http://localhost/authors?select=id,name
查询书籍id大于 100,且作者姓名在['x', 'y', 'z']中,并返回书籍的id, name和作者的id, name,并按照书籍id倒序排序。
curl http://localhost/books?select=id,name,author{id,name}&id=gt.100&author.name=in.x,y,z&order=id.desc
返回数据:
{
"count": 2,
"object_list": [
{
"id": 2,
"name": "Javascript",
"author": {
"name": "x",
"id": 2
}
},
{
"id": 1,
"name": "Python",
"author": {
"name": "y",
"id": 1
}
}
],
"is_paginated": false,
"page": 1
}
有兴趣的可以直接查看项目中的 DEMO:https://github.com/dracarysX/django-rest-query/tree/master/demo
PS
目前仅仅实现了 Django orm 和 Peewee 的解析。感兴趣的同学可以多多提意见和 issue,谢谢。
Python中如何实现一款no-sql风格的Rest API查询框架,支持Django ORM和peewee
感觉类似 Graph API ?
要实现一个支持Django ORM和Peewee的NoSQL风格REST API查询框架,核心是解析URL查询参数并将其转换为ORM的查询条件。下面是一个基于Django REST framework和Peewee的简单实现示例。
首先,安装必要的包:
pip install django djangorestframework peewee
1. Django ORM 实现
创建一个Django视图,解析查询参数:
# views.py
from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import YourModel
class NoSQLStyleAPIView(APIView):
def get(self, request):
query_params = request.query_params
queryset = YourModel.objects.all()
# 解析查询参数,例如:?name=John&age__gt=25
for key, value in query_params.items():
if '__' in key:
# 处理带操作符的查询,如 age__gt
field, op = key.split('__', 1)
lookup = f'{field}__{op}'
queryset = queryset.filter(**{lookup: value})
else:
# 精确匹配
queryset = queryset.filter(**{key: value})
# 支持OR查询,例如:?q=name:John,age:25
q_param = query_params.get('q', '')
if q_param:
q_objects = Q()
for pair in q_param.split(','):
if ':' in pair:
field, val = pair.split(':', 1)
q_objects |= Q(**{field: val})
queryset = queryset.filter(q_objects)
# 序列化并返回结果
from .serializers import YourModelSerializer
serializer = YourModelSerializer(queryset, many=True)
return Response(serializer.data)
2. Peewee 实现
对于Peewee,实现类似逻辑:
# peewee_view.py
from peewee import Model, CharField, IntegerField
from playhouse.shortcuts import model_to_dict
import json
# 定义Peewee模型
db = SqliteDatabase('my_database.db')
class YourPeeweeModel(Model):
name = CharField()
age = IntegerField()
class Meta:
database = db
def no_sql_style_api(request):
query_params = request.GET
query = YourPeeweeModel.select()
# 解析查询参数
for key, value in query_params.items():
if '__' in key:
field, op = key.split('__', 1)
# 将操作符映射到Peewee的查询方法
if op == 'gt':
query = query.where(getattr(YourPeeweeModel, field) > value)
elif op == 'lt':
query = query.where(getattr(YourPeeweeModel, field) < value)
else:
# 其他操作符处理
pass
else:
query = query.where(getattr(YourPeeweeModel, key) == value)
# 支持OR查询
q_param = query_params.get('q', '')
if q_param:
from peewee import fn
conditions = []
for pair in q_param.split(','):
if ':' in pair:
field, val = pair.split(':', 1)
conditions.append((getattr(YourPeeweeModel, field) == val))
if conditions:
query = query.where(fn.OR(*conditions))
# 转换为字典并返回JSON
results = [model_to_dict(obj) for obj in query]
return json.dumps(results)
总结建议 这个框架的核心是灵活解析查询参数并映射到ORM的查询方法,根据需求扩展操作符和逻辑即可。
楼主看过 postgrest 这个项目吗
嗯,就是看了这个项目才开始做的。

