Forms Django 2 UserCreationForm未创建用户
我使用django电子邮件作为用户名,这样用户就可以不用用户名进行身份验证,而是使用他们的电子邮件。似乎当我尝试注册一个新用户时,我被重定向回表单页面,而用户没有被创建。我是否应该在视图中包含已清理的数据 有什么建议吗 forms.pyForms Django 2 UserCreationForm未创建用户,forms,python-3.x,django-views,django-2.0,Forms,Python 3.x,Django Views,Django 2.0,我使用django电子邮件作为用户名,这样用户就可以不用用户名进行身份验证,而是使用他们的电子邮件。似乎当我尝试注册一个新用户时,我被重定向回表单页面,而用户没有被创建。我是否应该在视图中包含已清理的数据 有什么建议吗 forms.py from django import forms from django.contrib.auth import (authenticate, get_user_model, password_v
from django import forms
from django.contrib.auth import (authenticate, get_user_model,
password_validation)
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.utils.translation import ugettext_lazy as _
from cuser.models import CUser
UserModel = get_user_model()
class AuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
email/password logins.
"""
email = forms.EmailField(
label=_("Email address"),
max_length=254,
widget=forms.EmailInput(attrs={'autofocus': True}),
)
password = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput,
)
error_messages = {
'invalid_login': _(
"Please enter a correct %(username)s and password. Note that both "
"fields may be case-sensitive."
),
'inactive': _("This account is inactive."),
}
def __init__(self, request=None, *args, **kwargs):
"""
The 'request' parameter is set for custom auth use by subclasses.
The form data comes in via the standard 'data' kwarg.
"""
self.request = request
self.user_cache = None
super().__init__(*args, **kwargs)
self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
def clean(self):
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if email and password:
self.user_cache = authenticate(self.request, email=email, password=password)
if self.user_cache is None:
# An authentication backend may reject inactive users. Check
# if the user exists and is inactive, and raise the 'inactive'
# error if so.
try:
self.user_cache = UserModel._default_manager.get_by_natural_key(email)
except UserModel.DoesNotExist:
pass
else:
self.confirm_login_allowed(self.user_cache)
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
"""
Controls whether the given User may log in. This is a policy setting,
independent of end-user authentication. This default behavior is to
allow login by active users, and reject login by inactive users.
If the given user cannot log in, this method should raise a
``forms.ValidationError``.
If the given user may log in, this method should return None.
"""
if not user.is_active:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given email and
password.
"""
error_messages = {
'password_mismatch': _("The two password fields didn't match."),
}
email = forms.EmailField(
label=_("Email address"),
max_length=254,
widget=forms.EmailInput(attrs={'autofocus': True}),
)
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput,
help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput,
strip=False,
help_text=_("Enter the same password as before, for verification."),
)
class Meta:
model = CUser
fields = []
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def _post_clean(self):
super()._post_clean()
# Validate the password after self.instance is updated with form data
# by super().
password = self.cleaned_data.get('password2')
if password:
try:
password_validation.validate_password(password, self.instance)
except forms.ValidationError as error:
self.add_error('password2', error)
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
email = forms.EmailField(
label=_("Email address"),
max_length=254,
widget=forms.EmailInput(),
)
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=_(
"Raw passwords are not stored, so there is no way to see this "
"user's password, but you can change the password using "
"<a href=\"{}\">this form</a>."
),
)
class Meta:
model = CUser
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password'].help_text = self.fields['password'].help_text.format('../password/')
f = self.fields.get('user_permissions')
if f is not None:
f.queryset = f.queryset.select_related('content_type')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
url.py
from django.urls import path
from django.conf.urls import include, url
from accounts import views
urlpatterns = [
path('', views.index, name='index'),
path('register/', views.register, name='register'),
register.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>
<h1>Register</h1>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
登记
{%csrf_令牌%}
{{form.as_p}}
提交
您看过自定义用户吗?似乎确实提到了您提到的内容,但作为警告,它要求您在第一次迁移时这样做
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>
<h1>Register</h1>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>