Django创建没有密码的新用户

时间:2016-02-29 00:12:28

标签: python django django-forms

我使用自定义UserCreationForm创建新用户,然后使用auth.views中的password_reset和自定义电子邮件模板向用户发送注册邮件。此过程运行正常,用户可以成功完成注册过程并开始使用该应用程序。我现在想要创建用户而无需为用户设置密码。我尝试将self.fields [' password1']。required和self.fields [' password2']设置为False 在建议here的UserCreationForm init方法中,但这对我没有用。不幸的是,它证明难以调试。我没有看到任何错误消息,但我知道RegisterView寄存器方法没有被调用。

这是我的UserCreationForm

class UserCreateForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ("email",)

    def __int__(self):
        self.fields['password1'].required = False
        self.fields['password2'].required = False

    def save(self, commit=True):
        user = super(UserCreateForm, self).save(commit=False)
        clean_email = self.cleaned_data["email"]
        user.email = clean_email
        if commit:
            user.save()
        custom_user = CustomUser()
        custom_user.id = user
        custom_user.save()
        return user

这是我的RegistrationView

class UserRegistration(RegistrationView):
    def __init__(self):
        self.form_class = UserCreateForm
        self.success_url = 'login'
        self.template_name = 'register.html'

    def register(self, request, form):
        new_user = form.save()

我正在使用Django 1.8。如果有任何其他信息可用于分享,请告诉我。

2 个答案:

答案 0 :(得分:4)

如您所述,您修改了表单字段以不需要密码,但该模型呢?内置User模型强制使用密码(它是必需的模型字段),如果您尝试保存没有密码的User对象,则会出错。当您不想设置真实密码时,有一种特殊的方法 - set_unusable_password。在保存表单数据之前,请在视图中使用它。

答案 1 :(得分:3)

通过编程,您可以 create / save没有密码参数的新User,并且不会引发例外。实际上,您甚至可以create个没有任何参数的用户。 docs对此进行了说明。

例如,您可以在代码中执行此操作:

User.objects.create(username='user without password')

然后,数据库字段password将包含一个空字符串。因为用户现在已经存在,所以管理员将显示UserChangeForm,并且密码将显示为here,其中显示“ 未设置密码。”,如您所见。在下图中。您可以从那里正常进行。

ReadOnlyPasswordHashField

请注意,此空密码与screenshot of admin site 不同PasswordResetView unusable password,但是确实使用空密码。

还请注意,User.objects.create(password='')有效,但是User.objects.create(password=None)无效:由于数据库中的IntegrityError约束,NOT NULL会产生from django.test import TestCase from django.contrib.auth.models import User from django.contrib.auth.hashers import make_password import django.db import django.db.transaction RAW_PASSWORD = 'mypassword' class UserTests(TestCase): def tearDown(self) -> None: # print passwords as stored in test database for user in User.objects.all(): print(f'username: {user.username}\tpassword: {user.password}') def test_user_create_missing_required_fields(self): # none of these raise any exceptions, despite required model fields user_kwargs = [dict(), dict(username='a'), dict(username='b', password=''), dict(username='c', password=RAW_PASSWORD)] for kwargs in user_kwargs: user = User.objects.create(**kwargs) # password is "usable" ... self.assertTrue(user.has_usable_password()) if 'password' in kwargs: # stored password is still raw (not hashed) self.assertEqual(kwargs['password'], user.password) # ... but password-check fails self.assertFalse(user.check_password(kwargs['password'])) def test_user_set_password(self): # can set a usable password after user creation user = User(username='d') user.set_password(RAW_PASSWORD) # does not save... user.save() self.assertTrue(user.has_usable_password()) self.assertNotEqual(RAW_PASSWORD, user.password) self.assertTrue(user.check_password(RAW_PASSWORD)) def test_user_create_hashed_password(self): # we can initialize with a hashed password hashed_password = make_password(RAW_PASSWORD) user = User.objects.create(username='e', password=hashed_password) self.assertTrue(user.has_usable_password()) self.assertTrue(user.check_password(RAW_PASSWORD)) def test_user_set_unusable_password(self): # can set an unusable password user = User(username='f') user.set_unusable_password() # does not save... user.save() self.assertFalse(user.has_usable_password()) @django.db.transaction.atomic def test_user_create_password_none(self): # cannot initialize with password=None (violates the NOT NULL constraint) with self.assertRaises(django.db.IntegrityError) as a: User.objects.create(username='g', password=None) self.assertIn('not null', str(a.exception).lower()) def test_user_set_password_none(self): # can set None in set_password(), but that becomes unusable user = User(username='h') user.set_password(None) user.save() self.assertFalse(user.has_usable_password())

仅是为了说明选项,这是一个使用不同方式创建用户的测试:

alter account set saml_identity_provider = '{
"certificate": "...",
"ssoUrl": "https://login.microsoftonline.com/..../saml2",
"type": "custom",
"label": "AzureAD"
}';
alter account set sso_login_page=TRUE;
CREATE USER userA PASSWORD = '' LOGIN_NAME = 'userA.surname@example.com' DISPLAY_NAME = 'UserA';