Restiful 风格 的 接口 跟 增删改查方法。
jumpserver 中 用了大量这样的接口, 看源码
api.AdminUserAuthApi.as_view(), name='admin-user-auth'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.AdminUserTestConnectiveApi.as_view(), name='admin-user-connective'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/push/$',
api.SystemUserPushApi.as_view(), name='system-user-push')
rest_framework 接口 很容易看出 这个接口使用的action,关于 接口 的action 的关系 贴出如下。
{prefix}/ GET list 查询列表
{prefix}/ POST create 提交数据
{prefix}/{pk}/ Get retrieve 查询某条详情
{prefix}/{pk}/ PUT update 更新某条数据所有字段
{prefix}/{pk}/ PATCH partial_update 更新某条数据部分字段
{prefix}/{pk}/ DELETE destroy 删除某条数据
例如,如果 GET 方法 到了视图函数,只有prefix 就是 list action , 加上 pk 就是 成为了 retrieve action ,其中pk 可以是 根据lookup_field 来定义。
太累了,头晕,就举个 patch 方法 执行过程 来 分析 jumpserver 的 源码执行过程,关于url 怎么 路由,前面几个章节说过了,值了直接分析 ,update 方法,贴出源码
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data)
这个代码 很简单,首先partial 布尔值 为真 就是 部分 更新对象, 然后 贴出 get_serializer 源码
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
kwargs 形参 接受 了 update 方法中 传递给它的两个 参数 request.data 跟 partial 两个字段,可以看看 kwargs 里存了什么,只要自己写个小demo ,打印一下 其实 保留了 这些东西,贴出来
{'data': <QueryDict: {'bcommet': ['100']}>, 'partial': True, 'context': {'request': <rest_framework.request.Request object at 0x04F88C50>, 'format': None, 'view': <ggtest.views.Jsonview object at 0x04F88CF0>}}
然后 就实例化了 serializer_class 类,在实例化过程中具体发生 就是实例化 serializer_class 一个对象,真正对 数据做出修改的 动作是perform_update 方法,这个方法又是干什么 ,下面贴出源码,
def perform_update(self, serializer):
serializer.save()
save 方法源码 在这里
def save(self, **kwargs):
"""
Save and return a list of object instances.
"""
# Guard against incorrect use of `serializer.save(commit=False)`
assert 'commit' not in kwargs, (
"'commit' is not a valid keyword argument to the 'save()' method. "
"If you need to access data before committing to the database then "
"inspect 'serializer.validated_data' instead. "
"You can also pass additional keyword arguments to 'save()' if you "
"need to set extra attributes on the saved model instance. "
"For example: 'serializer.save(owner=request.user)'.'"
)
validated_data = [
dict(list(attrs.items()) + list(kwargs.items()))
for attrs in self.validated_data
]
if self.instance is not None:
self.instance = self.update(self.instance, validated_data)
assert self.instance is not None, (
'`update()` did not return an object instance.'
)
else:
self.instance = self.create(validated_data)
assert self.instance is not None, (
'`create()` did not return an object instance.'
)
return self.instance
其实中间 有点用 update 方法 完成了 对 数据的修改。