关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
在第一篇初步使用tastypie的体悟中提到可以自定义资源访问终点,即prepend_urls实现了Django登录功能。往往这些自定义的不符合restful风格,只有特殊情况才使用。(后面我还会分享一些使用prepend_urls的一些知识)。
那么,用户注册是否也需要自定义一个访问终点?
之所以这么问,因为我在实践中发现直接post提交用户名和密码。新建的用户是空密码,tastypie没有给我们写入密码信息。
这种情况比较特殊,因为Django的User模型需要对密码加密,无法直接写入原始密码。所以直接post得到的user是空密码。
面对这种情况,可以使用自定义资源访问终点。也可以不需要自定义访问终点。
在可以不需要自定义的情况下,尽量不要自定义。我们只需要重写obj_create方法即可。
先把User的ModelResource写好,如下代码:
#coding:utf-8 from tastypie.resources import ModelResource from tastypie.authorization import Authorization from django.contrib.auth.models import User class UserResource(ModelResource): class Meta: resource_name = 'user' # 名称 queryset = User.objects.all() # 数据集 # 只显示哪些字段 fields = ['username', 'email',] # 允许的请求方式 list_allowed_methods = ['get', 'post'] detail_allowed_methods = ['get', 'patch'] # 权限 authorization = Authorization()
接着,在该class中加入如下方法:
def obj_create(self, bundle, **kwargs): # 执行被重写之前的代码,实现新建user bundle = super(UserResource, self).obj_create(bundle, **kwargs) # 获取post提交的password参数 password = bundle.data['password'] # 给新建的user设置密码 bundle.obj.user.set_password(password) bundle.obj.user.save() return bundle
UserResource本质上还是class类,其中的方法可以被继承和重写。
obj_create方法源代码可以看tastypie包中的resources.py文件,找到BaseModelResource类。
该方法是tastypie创建对象的方法。
我们可以利用该方法在创建对象之前或之后做一些小动作实现我们想要的功能。
所以,我们利用该特性可以实现post创建user之后。使用bundle.obj得到新创建的user,对其写入密码。其中,set_password是Django提供的方法。
至于,bundle.data和bundle.obj两者是有区别。简单来说,bundle.data是一个dict。而bundle.obj是实际的模型对象。若要修改具体的模型对象可以直接使用bundle.obj。
上面这种重写方法的用法在tastypie的官方文档也有提及,可自行查阅。
obj_create对应post新建,还有obj_update方法可以被我们继承和使用。obj_update是对应patch提交修改数据。这些具体实现你可以自行实践。
上面的完整代码如下:
#coding:utf-8 from tastypie.resources import ModelResource from tastypie.authorization import Authorization from django.contrib.auth.models import User class UserResource(ModelResource): class Meta: resource_name = 'user' # 名称 queryset = User.objects.all() # 数据集 # 只显示哪些字段 fields = ['username', 'email',] # 允许的请求方式 list_allowed_methods = ['get', 'post'] detail_allowed_methods = ['get', 'patch'] # 权限 authorization = Authorization() def obj_create(self, bundle, **kwargs): # 执行被重写之前的代码,实现新建user bundle = super(UserResource, self).obj_create(bundle, **kwargs) # 获取post提交的password参数 password = bundle.data['password'] # 给新建的user设置密码 bundle.obj.user.set_password(password) bundle.obj.user.save() return bundle