文章目录
- 一、模型类设计
- 1、Django认证系统提供了用户模型类User,为什么还要定义User模型类?
- 2、AbstractUser
- 3、自定义用户模型类的字段有
- 4、User模型类编写好了就可以了吗?
- 二、序列化器类设计
- 1、注意
- 2、单字段进行校验
- 3、用户认证的时候为什么不用create,而用create_user呢?
- 三、视图类设计
- 1.注意
- 2.APIView子类
- 四.路由配置
- 1.特别注意:
一、模型类设计
1、Django认证系统提供了用户模型类User,为什么还要定义User模型类?
Django认证系统提供了用户模型类User,具体位置:django.contrib.auth.models.User;
因为Django认证系统提供的用户模型类User中缺少我本次项目中需要的字段,需要重写定义User模型类,最好不要和User重名,我以UserModel命令
2、AbstractUser
自定义的UserModel需要继承AbstractUser(User也继承了AbstractUser),同时还需要继承BaseModel
AbstractUser源码如下:
class AbstractUser(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator()
.....
class User(AbstractUser):
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
3、自定义用户模型类的字段有
phone:手机号
real_name:真实名字
roles:用户的角色
dept:所在部门
代码如下:
# ERP系统的用户模型类,默认采用django自带的User类
class UserModel(AbstractUser, BaseModel):
phone = models.CharField(help_text='手机号码',
verbose_name='手机号码',
max_length=11,
unique=True,
blank=True,
null=True)
real_name = models.CharField(help_text='真实名字',
verbose_name='真实名字',
max_length=64,
blank=True,
null=True)
# 用户所有的角色
roles = models.ManyToManyField('RolesModel', db_table='t_users_roles', blank=True)
dept=models.ForeignKey('DeptModel',blank=True,null=True,on_delete=models.SET_NULL,verbose_name='用户所在部门') #当部门删除后,员工的外键设置为null
class Meta:
db_table = 't_user'
verbose_name = '系统用户表'
verbose_name_plural = verbose_name
def __str__(self):
# return self.username+":"+self.real_name
return self.username
4、User模型类编写好了就可以了吗?
当然不是了,Django不会识别到你自己定义的User模型类,此时Django还是识别系统自带的User模型类,那需要怎么做
需要在settings.py配置文件中配置
特别注意:添加自定义用户模型类(应用名字.模型类名)
AUTH_USER_MODEL='erp_system.UserModel'
二、序列化器类设计
1、注意
1、extra_kwargs:当对模型类中定义的字段进行细微的调整时,在序列化器类中使用extra_kwargs进行调整
2、模型类中字段如果有设置为unique=True时,当校验不通过,在序列化输出时,并不是我想要的校验结果,可以通过
“validators”: [UniqueValidator(queryset=UserModel.objects.all(), message=‘用户名已注册,请重新输入’)],进行自定义.
3、一定要记住password字段,一定不能输出,要设置为’write_only’: True,
2、单字段进行校验
当在extra_kwargs={}中没法进行细微的调整时,需要进行单字段校验
采用validate_属性名称
例如当对手机号进行校验时,
用validate_phone(attr)
必须返回attr
拓展:
多字段校验:validate(attrs)
3、用户认证的时候为什么不用create,而用create_user呢?
UserModel.objects.create(**validated_data)
:
create:只会将反序列化输入校验通过的字段,原样插入到数据库中,因为密码是不能直接插入到数据中的
所以必须要重写create方法.
代码如下:
def create(self,validated_data):
'''必须重写create函数,因为用户密码是不能直接插入到数据库的'''
user=UserModel.objects.create_user(**validated_data)
return user
from rest_framework.serializers import ModelSerializer
from erp_system.models import UserModel
from rest_framework.exceptions import ValidationError
import re
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
class UserRegisterSerializer(ModelSerializer):
"""
用户注册的序列化器类
作用:序列化、反序列化、对字段进行严格验证
"""
class Meta:
model = UserModel
fields = ['id', 'username', 'password', 'phone', 'real_name','token']
extra_kwargs = {
'password': {
'write_only': True,
'max_length': 18,
'min_length': 4,
'help_text': '密码',
'label': '密码',
'error_messages': {
'min_length': "允许输入4-18个字符",
'max_length': "允许输入4-18个字符"
},
},
'username': {
'write_only': True,
'help_text': '用户名',
'label': '用户名',
'max_length': 18,
'min_length': 2,
'error_messages': {
'min_length': "允许输入2-18个字符",
'max_length': "允许输入2-18个字符"
},
"validators": [UniqueValidator(queryset=UserModel.objects.all(), message='用户名已注册,请重新输入')]
},
'real_name': {
'help_text': '真实姓名',
'label': '真实姓名',
'max_length': 64,
'min_length': 2,
'error_messages': {
'min_length': "允许输入2-64个字符",
'max_length': "允许输入2-64个字符"
}
}
}
def validate_phone(self, attr):
print()
# 验证手机号,验证规则(validate_属性名称)
if not attr:
return attr
else:
if not re.match(r'^1[3589]\d{9}$', attr):
raise ValidationError('请输入正确的手机号码')
return attr
def create(self,validated_data):
'''必须重写create函数,因为用户密码是不能直接插入到数据库的'''
user=UserModel.objects.create_user(**validated_data)
return user
三、视图类设计
1.注意
当视图类中需要用的接口包括增删改查查时,不用想直接继承ModelViewSet即可
当视图类中只实现某1个功能,只需要继承特定的视图类即可,不能继承ModelViewSet.
因为会有漏洞,不法分子会恶意访问接口进行修改数据.
2.APIView子类
ListAPIView
CreateAPIView
UpdateAPIView
RetrieveAPIView
DestroyAPIView
ListCreateAPIView
RetrieveUpdateAPIView
RetrieveDestroyAPIView
RetrieveUpdateDestroyAPIView
from rest_framework.generics import CreateAPIView
from erp_system.models import UserModel
from erp_system.serializer.user_serializer import UserRegisterSerializer
class RegisterView(CreateAPIView):
"""
create:
注册用户
参数:username,password 必须传递;phone,real_name 可选参数,return:添加返回的user对象
"""
queryset = UserModel.objects.all()
serializer_class = UserRegisterSerializer
四.路由配置
urlpatterns = [
# re_path(r'^user/login/$',obtain_jwt_token), #以/结尾 JWT签发和认证token的视图类
re_path(r'user/register/$',RegisterView.as_view()), #用户注册路由
]
1.特别注意:
当数据库脚本生成和迁移操作时,如果数据库中没有生成对应的表,
首先需要检查模型类设计是否正确;
接着将迁移脚本都删除,同时将数据库中的表也删除
重新执行迁移脚本(init.py文件不要删)