# 01.用户路由
[toc]{type: "ol", level: [2, 3, 4, 5]}
### 继承用户类
```python
### user.models
from django.contrib.auth.models import AbstractUser
from django.db import models
# Create your models here.
class User(AbstractUser):
telephone = models.CharField(max_length=11, verbose_name='phone_num')
```
<br><br>
### 配置用户类
```python
### settings.dev
AUTH_USER_MODEL = 'user.User'
```
<br><br>
### 序列化用户类
```python
### user.serializers
from rest_framework import serializers
from user.models import User
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
# 排除某个字段
# exclude = ['user_permissions']
def validate(self, attrs):
from django.contrib.auth import hashers
# 加密密码数据
attrs['password'] = hashers.make_password(attrs['password'])
return attrs
```
#### 用户注册序列化类
```python
### user.serializers
from rest_framework import serializers
from user.models import User
class UserRegisterSerializer(serializers.Serializer):
username = serializers.CharField(
max_length=12, min_length=2,
error_messages={
'required': 'must fill username',
}
)
password = serializers.CharField(max_length=12, min_length=2, write_only=True)
# 将其设置为只写状态 避免视图层无法读取数据而导致报错
confirm_password = serializers.CharField(max_length=12, min_length=2, write_only=True)
# 方式1:针对单个数据 注意不要写成:validated
def validate_confirm_password(self, data):
# data: confirm_password
# 必须与已经初始化的数据password进行对比!!!
if data != self.initial_data['password']:
raise serializers.ValidationError('password is different')
else:
return data
# 方式2:针对全部数据
def validate(self, attrs):
# if attrs['password'] != attrs['confirm_password']:
# raise serializers.ValidationError('password is different')
# # 不要返回confirm_password属性,否则数据将多余
del attrs['confirm_password']
return attrs
def create(self, validated_data):
# create_user为django自带的模块
return User.objects.create_user(
username=validated_data.get('username'),
email=validated_data.get('email'),
# 可在此处进行加密
password=validated_data.get('password'),
)
# 如果使用下面的方法,则必须删除confirm_password属性
# 此方法虽然简洁,但通过该方法创建的密码不会被加密
# return User.objects.create(**validated_data)
# 如果不重写该方法,则修改密码时,默认的update方法不会加密该数据
# 如果不想重写该方法,可以在UserSerializer的validate方法中进行设置
def update(self, instance, validated_data):
pass
```
<br><br>
### 创建用户视图
```python
from rest_framework import viewsets, status
from rest_framework import mixins
from rest_framework.response import Response
from rest_framework.decorators import action
from .serializers import *
# 此处如果使用ModelViewSet,则用户可以获取其他用户的信息
class UserGenericViewSets(
viewsets.GenericViewSet,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
):
queryset = User.objects.all()
serializer_class = UserModelSerializer
# 方式1:添加注册功能
@action(methods=['POST'], detail=False)
# 自动将路由添加到urls中:http://127.0.0.1:8000/user/api/v1/users/register/
def register(self, request):
seria = UserRegisterSerializer(data=request.data)
if seria.is_valid(raise_exception=True):
seria.save()
# 因为attrs[confirm_password]已被删除,未保存到数据库中
# 因此,要将重复密码设置为:write_only 禁止seria.data 查找该属性
return Response(seria.data, status=status.HTTP_201_CREATED)
# 方式2:不定义register方法
# 方式2的优先级高于方式1:serializer_class = UserSerializer
def get_serializer_class(self):
# action: 请求方式对应的方法
# POST请求时,使用UserRegisterSerializer
# 其他请求时,使用UserSerializer
# 使用的路由:http://127.0.0.1:8000/api/v1/users/
if self.action == 'create':
return UserRegisterSerializer
return UserModelSerializer
```
<br><br>
### 创建用户路由
```python
from django.urls import path, include
from . import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
# 注册路由
router.register('users', views.UserGenericViewSets)
urlpatterns = [
path('api/v1/', include(router.urls)),
]
```
<br><br>
### 进入路由
http://127.0.0.1:8000/user/api/v1/users/
![drf](imgs/01.png)
http://127.0.0.1:8000/user/api/v1/users/1/
![drf](imgs/02.png)
<br><br>