三、用户的增删改查——注册接口

简单写法(松勤):

1.定义序列化器

class UserSerializer(ModelSerializer):

    class Meta:
        model=User
        read_only_field=["id"]
        # exclude=['password']
        fields = "__all__"

2.定义视图集

from rest_framework.permissions import AllowAny
# 1.用户管理视图集
class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]

补充: 密码加密用  make_password

from django.contrib.auth.hashers import make_password

class UserSerializer(ModelSerializer):
    """
    用户管理-序列化器
    """
    class Meta:
        model = User
        read_only_field = ["id"]
        # exclude=['password']
        fields = "__all__"

    def create(self, validated_data):
        # 对validated_data进行处理或修改后再保存到数据库
        validated_data['password']=make_password(validated_data['password'])
        validated_data['is_staff']=1
        return super().create(validated_data)

3.配置url

from rest_framework.routers import DefaultRouter
router=DefaultRouter()
router.register('users',views.UserViewSet)

urlpatterns = []
urlpatterns += router.urls

列表接口: 

 新增(注册接口)?有问题待解决

复杂点的(柠檬)

  • 注册后要返回token
  • 要验证密码和确认密码媳妇是你

在【users应用】中的serializers.py 中

需求:

  • 需要修改User 的序列化器,吧 email 字段改成必传
  • 确认密码、和token 是 模型 的额外的字段,需要添加
  • 密码和确认密码需要做一个联合校验,”两次输入密码要一致“validate 中
  • 用户名要求 “仅允许6-20个字符的用户名”
  • 密码要求“仅允许6-20个字符的密码”
  • 用户名验重(已又有的),增加email验重
  • 登录成功后,返回token(要使用TokenObtainPairSerializer()的get_token(user)方法)
  • User模型,新增数据,是用User.objects.create_user
  • 响应只返回三个字段(id,username, token)
from rest_framework.serializers import ModelSerializer

from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.validators import UniqueValidator

from utils.jwttoken import MyTokenObtainPairSerializer
class RegisterModelSerializer(ModelSerializer):
    password_confirm = serializers.CharField(label='确认密码',help_text='确认密码',write_only=True,
                                             max_length=20, min_length=6,
                                             error_messages={
                                                            'min_length': '仅允许6-20个字符的密码',
                                                            'max_length': '仅允许6-20个字符的密码',
                                                            'required': '密码必填(可选)'}
                                           )

    token = serializers.CharField(label='生成token',help_text='生成token',read_only=True)

    def validate(self, attrs):
        password = attrs.get('password')
        password_confirm = attrs.get('password_confirm')
        if password != password_confirm:
            raise serializers.ValidationError("确认密码和密码不一致")
        return attrs

    def create(self, validated_data):
        #  删除多余的字段,确认密码
        validated_data.pop('password_confirm')

        """这里要注意,不能用传统的 模型。object。create(), 因为这样传递的密码是没有加密的,需要用create_user"""
        user = User.objects.create_user(username=validated_data.get("username"),
                                        email=validated_data.get('email'),
                                        password=validated_data.get('password'))

        # 生成token(没有自定义的序列化器,就用from rest_framework_simplejwt.serializers import TokenObtainPairSerializer  ,这个获取token序列化器)
        serializers=MyTokenObtainPairSerializer()
        user.token=serializers.get_token(user)

        return user


    class Meta:
        model = User
        fields  = ["id","username","password","password_confirm","email","token"]
        extra_kwargs = {
        'username':{
            'max_length':20,
            'min_length':6,
            'error_messages':{
                'min_length': '仅允许6-20个字符的用户名',
                'max_length': '仅允许6-20个字符的用户名',
                'required': "名称必填"}
        },
        'password':{
            'max_length':20,
            'min_length':6,
            'write_only':True,
            'error_messages':{
                'min_length': '仅允许6-20个字符的密码',
                'max_length': '仅允许6-20个字符的密码',
                'required': "密码必填"}
        },
        'email':{
            'required':True,
            'write_only': True,
            'error_messages': {
                'required': "邮箱必传"},

            # 添加邮箱重复校验
            'validators': [UniqueValidator(
                                 	queryset=User.objects.all(),
                                  	message="此邮箱已注册"
                                 )]
        }

        }


views.py中,定义了视图类,继承的  GenericViewSet  ,那么url中,的as_view(), 就要接收字典

from .serializers import RegisterModelSerializer
from rest_framework import generics, mixins
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from django.contrib.auth.models import User


class RegisterModelView(mixins.CreateModelMixin, GenericViewSet):
    serializer_class = RegisterModelSerializer
    queryset = User.objects.all()

url.py中

 校验用户名是否存在接口、校验邮箱是否存在接口

视图类,不是继承的Set类,url.py 中,就直接as_view就好了

from rest_framework.views import APIView
from rest_framework.response import Response
class UserNameIsExistedView(APIView):
    def get(self,request,name):
        count=User.objects.filter(username=name).count()
        if "@" in name:
            count = User.objects.filter(email=name).count()
            return  Response({"email":name,"count":count})
        return Response({"username": name,"count":count})

 # 用户名和邮箱的校验
    re_path(r'^(?P<name>.{5,20})/count/$',UserNameIsExistedView.as_view())

效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值