如何使用 django 和 django Restframework 保存哈希密码和 send_mail?

问题描述 投票:0回答:1

我正在使用 django Restframework 构建一个端点,并且我有 Modelserializer 通过控制台使用 django 的电子邮件后端来序列化和发送电子邮件激活令牌。但是序列化器会保存部分字段,忽略散列密码,使用 send_mail() 发送电子邮件以及任何打印或记录语句。它给了我 201 响应。以下是代码 序列化器

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = [
            "first_name",
            "last_name",
            "email",
            "phone_number",
            "address",
            "zip_code",
            "company_name",
            "gender",
            "birthdate",
            "referral_code",
            "city",
            "district",
        ]
        read_only_fields = [
            "is_active",
            "is_staff",
            "is_superuser",
            "is_email_verified",
            "is_address_verified",
            "is_company_verified",
            "created_at",
            "updated_at",
            "login_attempts",
        ]
        extra_kwargs = {"password": {"write_only": True}}

        def create(self, validated_data):
            BASE_URL = "http://127.0.0.1:8000/api/p/users/"
            UID = urlsafe_base64_encode(force_bytes(user.pk))
            TOKEN = account_activation_token.make_token(user)
            sender_mail = "[email protected]"
            mail_subject = "Activation link has been sent to your email id"

            traceback.print_exc()
            print("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr")

            city1 = City.objects.get(pk=validated_data.pop("city"))
            district1 = District.objects.get(pk=validated_data.pop("district"))

            user = CustomUser(
                first_name=validated_data["first_name"],
                last_name=validated_data["last_name"],
                email=validated_data["email"],
                phone_number=validated_data["phone_number"],
                zip_code=validated_data["zip_code"],
                company_name=validated_data["company_name"],
                gender=validated_data["gender"],
                birthdate=validated_data["birthdate"],
                referral_code=validated_data["referral_code"],
                city=validated_data["city"],
                district=validated_data["district"],
            )
            user.set_password(validated_data["password"])

            # send OTP to user via email

            domain = (BASE_URL + "activate/" + UID + "/" + TOKEN,)
            logger.info("before sending email ------")
            email = send_mail(
                subject=mail_subject,
                message=domain,
                from_email=sender_mail,
                recipient_list=validated_data["email"],
                fail_silently=False,
            )
            user.otp = TOKEN
            email.send()
            logger.info("after sending email ------")
            user.save()
            return user

查看

class UserCreateView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

请问有什么帮助吗?

我尝试了所有可能的组合来实现它,实际上它的工作效率约为 80%,但 20% 对于系统也至关重要。我希望得到一个答案,让我保存散列密码、通过控制台发送电子邮件并打印并登录到控制台或用于调试目的的文件

django django-models django-rest-framework django-serializer
1个回答
0
投票

UserManager
有两个功能可以帮助用户创建,使用
AbstractBaseUser
时您应该设置一个。另一方面,
AbstractUser
为您设置内置管理器。在其最基本的形式中,它确保了哈希密码等。

send_mail
包裹在 try/ except 块中,并根据结果设置相应的响应,当然,如果您愿意,您可以随时进行概括。在本例中(这两个例外并没有涵盖所有情况),只有创建用户并发送电子邮件才会返回成功的响应。

序列化器.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        ...

    def create(self, validated_data):
        base_url = "http://127.0.0.1:8000/api/p/users/"
        uid = uuid.uuid4()
        token = uuid.uuid4()
        domain = f"{base_url}activate/{uid}/{token}"
        instance = User()

        try:
            is_sent = send_mail(
                "Activation link has been sent to your email id",
                domain,
                "[email protected]",
                [validated_data["email"]],
                fail_silently=False,
            )
            if is_sent > 0:
                validated_data['otp'] = token
                instance = User.objects.create_user(**validated_data)
                print(f'email sent to: {instance.email}')
            else:
                print(f'FAILED to send email to: {validated_data["email"]}')
        except SMTPException:
            print(f'FAILED to send email to: {validated_data["email"]}')
        except ConnectionRefusedError:
            print(f'FAILED to send email to: {validated_data["email"]}')

        return instance

views.py

class UserCreateView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            instance = serializer.save()
            if instance.pk:
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(
                    {"error": "Something went wrong."},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                )

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
© www.soinside.com 2019 - 2024. All rights reserved.