上一篇文章其实已经讲了一点登录验证相关的内容,不过主要还是为了回答一位群友关于定制DJango用户模型的提问而临时写的,认证(authentication)与授权(authorization)实质上是两个步骤,但是一般都放在一起讲,认证是识别身份,你用管理员账户登录,密码正确,身份被确认为管理员,这是认证,因为是文章作者,所以有编辑文章的权限,这是授权。
用户与文章应该是一对多的关系,首先要修改我们的Article模型:
接着去执行迁移操作:
注意到之前的文章都是没有作者的,所以执行迁移的时候会要求要么退出迁移,在模型上添加默认值,或者现在给出默认值。建议多熟悉迁移操作并且适当掌握一些SQL
用法,这种涉及到数据变更的,有时候还得手动解决冲突。这里给我们之前创建的管理员账户ID做默认值就行,当然开发环境简单粗暴点也可以直接删库。
先修改一下序列化器,加入author
字段:
然后用命令行工具httpie测试一下API:
可以正常创建新文章,但是,我们只要在POST请求里带上用户ID,就可以为任意用户创建文章,这是不可取的,现在来解决这个问题。
上一节已经讲过了自定义权限类,现在来写一个只允许管理员创建删除修改,其他用户只读的权限类。
新建article/permissions.py
:
继承父类的has_permission
方法,这个方法的返回值是布尔值,True
即表示授权通过,对任意用户的请求在SAFE_METHODS
内的,直接通过,否则就看用户是否是管理员。
现在要修改一下视图类:
现在再使用httpie测试,会得到错误响应:
现在带上验证信息再请求一次:
这次成功了,但是还有个问题,就是author
这个字段仍然需要传递,并且只要是管理员,这个author值可以填任何已存在的用户ID。现在再来修复这个问题。
这里覆写了父类的perform_create
方法,在序列化器保存时,从请求对象中获取user
值并赋值给author参数,但是用户仍然可以传递author字段,可以在序列化器中把它设置为只读:
再次测试:
这样即使传递了非法的author字段也会被忽略掉。