我使用自定义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。如果有任何其他信息可用于分享,请告诉我。
答案 0 :(得分:4)
如您所述,您修改了表单字段以不需要密码,但该模型呢?内置User
模型强制使用密码(它是必需的模型字段),如果您尝试保存没有密码的User
对象,则会出错。当您不想设置真实密码时,有一种特殊的方法 - set_unusable_password
。在保存表单数据之前,请在视图中使用它。
答案 1 :(得分:3)
通过编程,您可以 create
/ save
没有密码参数的新User
,并且不会引发例外。实际上,您甚至可以create
个没有任何参数的用户。 docs对此进行了说明。
例如,您可以在代码中执行此操作:
User.objects.create(username='user without password')
然后,数据库字段password
将包含一个空字符串。因为用户现在已经存在,所以管理员将显示UserChangeForm
,并且密码将显示为here,其中显示“ 未设置密码。”,如您所见。在下图中。您可以从那里正常进行。
请注意,此空密码与 不同。 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';