当使用 DRF 创建接口,并且自定义 user 模型时,遇到的问题及解决方案如下:
- 首先是 DRF 的安装问题,此处不再赘述,参考官方文档即可!
- 在model中自定义自己的用户类:
from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
"""
解决通过 DRF 创建用户时 密码明文的问题
"""
password = instance.password
instance.set_password(password)
instance.save()
class UserInfo(AbstractUser):
DEPARTMENT_CHOICES = {
(1, '测试部门'),
(2, '开发部门'),
(3, 'PM'),
(4, '其它部门'),
}
department = models.IntegerField(verbose_name='部门', choices=DEPARTMENT_CHOICES, default=1)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')
class Meta:
verbose_name_plural = verbose_name = '用户信息'
def __unicode__(self):
return self.username
-
关于上方的代码,有几个需要重点关注的地方:
- 关于模型类的创建,只需要继承
AbstractUser 这个基类,然后根据你的需要,重写其中的字段,或者新增一些字段,此处没什么需要注意的,只要按照正常的要求进行编写就可以了 - 这部分代码的重点是下面这部分
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
"""
解决通过 DRF 创建用户时 密码明文的问题
"""
password = instance.password
instance.set_password(password)
instance.save()
-
首先说明一下,上面的这段代码,是当通过接口或者admin后台创建用户时,在数据保存前通过监测 post_save 信号,来对数据进行额外的处理后,再进行保存。 -
restframework官方网站上,说明的情况都是针对直接使用django自带的 user 模型,但是往往这种自带的模型并不能适用各种的平台,所以在某些情况下,我们需要对其进行额外的定制处理 -
但是当我们使用自己创建的用户模型进行创建用户等操作时,我遇到了下面的两种情况: 1.新建用户密码明文的问题;
2通过 restframework 接口创建的用户无法通过指定接口获取token
-
首先说明一下为什么会导致上面的两个问题:
- 通过查询资料,我的理解是这样,用上面的代码进行举例,当我们新建用户时,调用的是
userinfo 的create方法,而不是django自带的user 的create的方法,此处就不知道django后面使用了什么机制,导致了这个问题。 - 通过上面监测
post_save 信号,在数据放入数据库前,我们调用了
password = instance.password
instance.set_password(password)
instance.save()
上面的这一部分代码,一下子就解决了上面的两个问题,通过instance.set_password(password) 解决了密码明文的问题,通过instance.save() 解决了使用userinfo 创建用户的问题
- 除此之外,
settings.py 中还有个配置需要增加一下:
AUTH_USER_MODEL = 'user.UserInfo'
"这个是用来覆盖django原有的user模型的"
AUTHENTICATION_BACKENDS = (
'rest_framework.authentication.TokenAuthentication',
'django.contrib.auth.backends.ModelBackend',
)
""这个配置目前还不知道发挥了什么作用,暂且写上吧""
- 下面的这个链接一下子解决了我的两个问题
[参考链接] (https://www.jianshu.com/p/af6c9225ac8d)
|