Introduction
It is an enhancement of django-crudapi project at first, but by now it has become an independent app.
介绍
一个 django 通用 crud 操作的实现,开始设计时参考了 django-crudapi
实现的特性:
- 通过简洁的 url 模式对所有的 django model 进行增删改查操作。如:
- GET /api/app/model/ 返回列表
- POST /api/app/model/?field1=value1&field2=value2... 创建一条记录
- GET /api/app/model/3 返回第三条数据的信息
- POST /api/app/model/3/?_method=put&field1=value1&field2=value2... 修改第三条记录
- POST /api/app/model/3/?_medhod=delete 删除第三条数据
对应的 url 设置如下:(r'^(?P<key>api)/', include('apps.resource.urls')),
- url 中设置参数,现在支持三个固定参数:
- _method: put or delete, 用于 POST 时代替 http 中的 PUT 和 DELETE 方法。
- _format: json or xml or html, 用于控制生成格式,默认为 json。
- _fields(0.96只支持xml格式,trunk 中都可用,django 序列化方法的 bug 已经修复): 限制一个 model class 中的返回 fields, 当作列表来处理,url 中可以这样 &_format=xml&_fields=name&_fields=code&...。
支持不固定的参数,可以在 GET 时添加搜索条件,如:
- GET /api/app/model/?name=some_name&id__lt=3 会返回 name 为 some_name 且 id < 3 的记录。
- 两种访问权限方式,api key 和 session (现有的代码暂时去掉了 api key 的方法,因为这样不用生成数据库表,如果想用的话可以参考models.py,同时将Resource.py中的get_user部分反注释即可)
- 支持多种返回格式,xml, json, html 片段,默认返回json格式,其中 html 片段使用 django 的 generic view,只需按命名规则创建模板即可。
- 可配置行为,可以通过继承 Resource 类来覆盖默认行为,比如我在 Resource 中添加的 before_update 钩子:
def before_update(self, request, obj):
# 同步设置当前修改时间和用户
if hasattr(obj, 'update_time'):
obj.update_time = datetime.today()
if hasattr(obj, 'update_user'):
obj.update_user = get_user(request)可以在 update 之前做一些额外的事情,将 update_user 设置为当前用户,将修改时间设置为当前时间等。类似的钩子还有 before_create, before_get_list 和 before_read。
- 支持一个 model 对应多个 api,见下面的用法说明
用法
resource 是一个django app,可以直接放入你的 app 目录下,并在 settings 中添加对应 INSTALLED_APPS 配置。最后在你的 urls.py 中 include resource 目录下的 urls.py 即可(推荐),例如:urls.py:
# -*- coding: utf-8 -*-
from django.conf.urls.defaults import *
from django.db import models
from apps.resource import register
from apps.resource.Resource import Resource
# 可以通过继承来覆盖默认方法
class MyResource(Resource):
cannot_see_fields = ['id', 'passwd']
# 这里注册了所有 model, 正式项目中应该有选择的进行注册
for model in models.get_models():
register('api', model, Resource)
# 支持一个 model 多个 api
register('another_api', model, MyResource)
urlpatterns = patterns('',
(r'^$', 'django.views.generic.simple.direct_to_template',
{'template': 'index.html'}),
(r'^admin/', include('django.contrib.admin.urls')),
(r'^(?P<key>api)/', include('apps.resource.urls')),
(r'^(?P<key>another_api)/', include('apps.resource.urls')),
)url中应该有个名为 key 参数。