1. 程式人生 > >Django 利用第三方平臺實現使用者註冊02

Django 利用第三方平臺實現使用者註冊02

前言:

  上篇部落格我們已經對設定了圖形驗證碼,簡訊驗證碼對使用者資訊進行了一些簡單的驗證,本篇部落格我們會將上篇的一些驗證方法進行結合,來進一步完成我們的註冊工作

1. 建立檢視類

  在user中的view建立CreateUserAPIView類,而且這個類繼承自APIView(一級檢視)

class CreateUserAPIView(APIView):

    def post(self,request):

        # 注意該類繼承自APIView,獲取post資料要用request.data

        data = request.data

        # 建立序列化器


        serializers = CreateUserAPIViewSerializers(data=data)

        serializers.is_valid(raise_exception=True)
        # 注意data中含有password2等User模型類中並沒有的欄位,需要在差un關鍵物件之前將這些欄位刪除
        # 因此需要重寫create方法

        serializers.save()
        # 返回響應

        return Response(serializers.data)

  2.建立序列化器CreateUserAPIViewSerializers

lass CreateUserAPIViewSerializers(serializers.ModelSerializer):
    """
    由於User類中沒有 password2 sms_code,allow資訊,因此無法自動生成該序列化欄位,需要手動建立


    """
    password2 = serializers.CharField(max_length=20,min_length=5,write_only=True,label="確認密碼")
    sms_code = serializers.CharField(max_length=6,min_length=6,write_only=True,label="簡訊驗證碼")
    allow = serializers.CharField(label="是否同意使用者協議",allow_blank=False,write_only=True)
    token = serializers.CharField(label='登入狀態token', read_only=True)  # 增加token欄位


    class Meta:
        model = User
        fields = ('id','username','password','password2','mobile','sms_code','allow','token','email_active')
        extra_kwargs = {
            'id': {'read_only': True},
            'username': {
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '僅允許5-20個字元的使用者名稱',
                    'max_length': '僅允許5-20個字元的使用者名稱',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '僅允許8-20個字元的密碼',
                    'max_length': '僅允許8-20個字元的密碼',
                }
            },
        }

    # 單個欄位驗證

    def validated_mobile(self,mobile):

        if re.match(r'1[345789]\d{9}',mobile):

            raise serializers.ValidationError('電話格式錯誤!')

        return mobile

    def validated_allow(self,allow):

        if allow != 'True':
            raise serializers.ValidationError("請勾選協議!")

    # 多個欄位驗證


    def validate(self, attrs):

        mobile = attrs.get('mobile') # 使用者輸入的電話
        sms_code = attrs.get('sms_code') # 使用者輸入的簡訊驗證碼

        password = attrs.get('password') # 第一次輸入的密碼
        password2 = attrs.get('password2') # 第二次輸入的密碼

        if password != password2:
            raise serializers.ValidationError("兩次輸入的密碼不一致!")


        # 獲取redis中的驗證碼

        sms_redis = get_redis_connection('smscode')

        smscode = sms_redis.get('sms_%s'%mobile) # redis中儲存的驗證碼
        if smscode is None:

            raise serializers.ValidationError('簡訊驗證碼已經過期!')

        if smscode.decode() != sms_code:

            raise serializers.ValidationError('簡訊驗證碼錯誤!')

        return attrs

    def create(self, validated_data):

        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['allow']


        user = User.objects.create(**validated_data)


        #修改密碼
        user.set_password(validated_data['password'])
        #注意儲存
        user.save()

        # 補充生成記錄登入狀態的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token

        return user

    上篇部落格也提到了建立序列化器的兩種方法,我會專門寫一篇部落格來詳細的說明這兩種方法

3. 將路由地址註冊到urls

urlpatterns = [
    ......
    url(r'^$',views.CreateUserAPIView.as_view()),

]

4. 驗證 

  這時當你輸入所有的資訊之後點選註冊時並沒有任何的反應,我們開啟瀏覽器的除錯工具,如下圖所示

  伺服器並沒有響應200,而是響應了400,這是怎麼回事呢?我發現我們請求之前的ip是127.0.0.1:8080,但我們卻向127.0.0.1:8000請求資料,這就會引發跨域的問題,那麼什麼是跨域,跨域怎麼解決呢?可以參考我之前的部落格:https://www.cnblogs.com/xuchuankun/p/9780896.html

  我們按照說明進行跨域配置之後,再來進行註冊驗證,結果我們就會發現我們的資料經過序列化器的校驗後成功的存入資料庫

  資料庫中的這條記錄就是剛剛我們註冊的資料,到此為止我們的註冊功能就實現了。我們還可以根據需求進行適當的修改。希望能幫助大家,同時也感謝大家的檢視