Django get_user_model().objects.create() 密码没有被散列

Django get_user_model().objects.create() password is not getting hashed

我有一个测试用例,它首先创建一个用户,然后尝试使用 Django authenticate() 方法对创建的用户进行身份验证,但看起来密码没有被散列,因此它无法检索令牌...我将分享与本节相关的任何代码,我认为必须对流程进行一些处理。

自定义用户模型管理器:

class UserManager(BaseUserManager):

def create_user(self, email, password=None, **extra_fields):
    """ Creates and saves a new user """

    if not email:
        raise ValueError("Users must have an email address.")

    user = self.model(
        email=self.normalize_email(email),
        **extra_fields
    )

    # Set password this way makes a hashed password
    user.set_password(password)
    user.save(using=self._db)

    return user

app/settings.py:

AUTH_USER_MODEL = "core.User" # 'User' is the name of custom user class

用户/serializers.py:

class UserSerializer(serializers.ModelSerializer):
    """ Serializer for the users object """

    class Meta:
        model = get_user_model()
        fields = ["email", "password", "name"]
        extra_kwargs = {
            "password": {
                "write_only": True,
                "min_length": 5,
            }
        }

    def create(self, validated_data):
        """ Create a new user with encrypted password and return it """
        user = get_user_model().objects.create(
            email=validated_data["email"],
            name=validated_data["name"]
        )
        user.set_password(validated_data["password"])
        print(f"from serializer: {user.password}")
        user.save()

        return user

最后是我的测试用例,user/tests/test_user.py:

  #...
  def test_create_token_for_user(self):
        """ Test that a token is created for the user """
        payload = {
            "email": "test@test.com",
            "password": "testpass"
        }
        user = get_user_model().objects.create(**payload)

        print(user.password) # returns 'testpass' in plain text...

        res = self.client.post(TOKEN_URL, payload)

        self.assertIn("token", res.data)
        self.assertEqual(res.status_code, status.HTTP_200_OK)

你应该在测试中使用create_user,所以:

def test_create_token_for_user(self):
    payload = {
        'email': 'test@test.com',
        'password': 'testpass'
    }
    #                     use create_user ↓
    user = get_user_model().objects.<b>create_user(**payload)</b>

    print(user.password)
    res = self.client.post(TOKEN_URL, payload)

    self.assertIn('token', res.data)
    self.assertEqual(res.status_code, status.HTTP_200_OK)

在序列化程序中,您还可以使用 .create_user():

class UserSerializer(serializers.ModelSerializer):
    # …

    def create(self, validated_data):
        user = get_user_model().objects.<b>create_user(</b>
            email=validated_data['email'],
            name=validated_data['name'],
            password=validated_data['password']
        <b>)</b>
        return user