写在前边的话
有时候想的很简单,我就想拿django写个api后台,有个类似api文档的东西就行了。可是搞到最后觉得好复杂啊,代码量也没见减少。自己写好多schema,就为了生成个api文档,要不就是想用rest_framework,就开始学序列化那一套,最后发现格式不是自己想要的。想自定义也不会,迷失在官方文档中,走不出来了。那么问题来了,到底怎么才能省点头发?我能不写schema,也能搞个api文档嘛?好多相似的curd逻辑,我能不写很多重复的代码不?练习django两年半归来,今天我试图教会你怎么简单省事的用django搭建个api后台。
最近把我个人搭建django项目的demo开源了,有需要的同学可以参考。
国内地址https://gitee.com/haiweifeng/django_open_project外网地址:
github地址https://github.com/haiweifeng/github_django_demo_project
设计思路
1. 关于类视图的使用思路
class MyUsersListView(ApiBaseView):
"""
获取后台用户列表信息
"""
model = MyUsers
_keys = [('name', '用户姓名',""), ('phone', '手机号',"")]
action_desc = "后台用户列表"
schema = create_normal_schema(_keys,add_page=True,add_token=True)
一个基本的查询页无非就是获取查询参数,查询对应的数据库表格,然后返回给前端。使用django的类视图继承,可以减少重复代码,减少开发时间。 关于apiBaseView的设计根据你自己的大部分逻辑来统一设计,遇到特殊的情况,可以重写get放法自己定义。 同理,增加,编辑,删除,其实都是相似的动作,所以都可以继承。类视图很强大,对比fastapi什么的,你用多了你就懂了。
2. 关于api文档的使用
很多时候我们在设计model的时候已经指定了每个字段的含义,想让它直接出现在api说明文档中,这样就省去了接口入参的定义方式。create_schema 和create_normal_schema 两个方法都是为了创建api文档,create_normal_schema 是为了创建一个数据库中没有的参数,你需要自己 写schema,标明参数的含义和默认值,create_schema是创建一个数据库中有的参数,你只需要定义是否必填,要不要带个默认值。 add_token 请求是否带上token,add_page 是否需要分页参数 add_id 是否需要id参数 等等,你都可以自己定义 create_schema 元组长度为1时,默认是必填,长度大于1时,默认不是必填
schema = create_normal_schema([('ids', '删除的id数组')], add_token=True)
key1 = [('name',), ('phone',), ('password',), ('account',)]
keys, schema = create_schema(MyUsers, key1,add_token=True)
3. 关于数据库查询操作
@staticmethod
def query_by_search(search, **kwargs):
result = NumberRoles.objects.filter(del_time=None)
if 'name' in search and search['name']:
result = result.filter(name__contains=search['name'])
if 'start_time' in search and search['start_time']:
startTime = datetime.datetime.strptime(search['start_time'], '%Y-%m-%d')
result = result.filter(created_time__gte=startTime)
if 'end_time' in search and search['end_time']:
endTime = datetime.datetime.strptime(search['end_time'], '%Y-%m-%d') + datetime.timedelta(days=1)
result = result.filter(created_time__lt=endTime)
total = result.count()
return total, result.order_by('-created_time').values()
apibaseview中,query_by_search方法就是用来查询数据库的,可以自己定义。通过重写get_data方法,可以指定查询的静态方法
4. 关于rabbitmq和socket的使用 我使用的django版本是5.0.6,启动方式默认daphne,所以走的是asgi模式,我把一些异步的方法都放在asgi.py中了,如果有需要自行放开使用
5. 关于异步的使用
def post(self, request):
vip_id = request.data.get('vip_id', '')
print("vip",vip_id)
after_task.after_response(vip_id)
# my_signal.send(sender=vip_id, msg='Hello world')
return json_res(code=200, msg=vip_id)
参看demo_test接口的使用方式,后续如果有需求也可以加上celery,反正目前没计划。我以前使用的都是celery,最近觉得这个可以试试。
6. 关于部署 环境包参考req.txt文件,使用supervisor部署项目,配置文件参考supervisor_conf中的配置文件。如果你不会用可以留言,我写个详细的教程