我有自定义用户模型,可以用于注册和创建超级用户。但是却无法登录。我一直在尝试纠正问题,但找不到任何潜在的错误...
当我提交表单时,登录表单没有登录用户,它只是说具有该用户名的用户已经存在(它的行为类似于注册页面)如何解决此问题,否则我会收到“页面无法访问联系人”该网站的所有者'
#models.py
class Organisation(models.Model):
organisation_name = models.CharField(max_length = 256)
contact_no = models.IntegerField()
email = models.EmailField()
class Meta():
unique_together = ['organisation_name','email']
def __str__(self):
return self.organisation_name
class MyUserManager(BaseUserManager):
def create_user(self, username, organisation, email, password):
if not organisation:
raise ValueError("Users must have an organisation")
email = self.normalize_email(email)
user = self.model(username=username, email=email, organisation=organisation)
user.set_password(password)
user.save(using=self.db)
return user
def create_superuser(self, username, email, password):
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.is_superuser = True
user.is_staff = True
user.save(using=self.db)
return user
class MyUser(AbstractBaseUser):
username = models.CharField(max_length=256,unique=True)
email = models.EmailField(max_length=256)
organisation = models.ForeignKey(Organisation,on_delete=models.CASCADE,null=True)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ['email']
objects = MyUserManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#forms.py
class MyUserForm(forms.ModelForm):
class Meta():
model = models.MyUser
fields = ('username','email','password','organisation')
class MyUserLoginForm(forms.ModelForm):
password=forms.CharField(label="password",widget=forms.PasswordInput)
class Meta:
model=models.MyUser
fields=("username","email","password","organisation")
#views.py
class indexPage(TemplateView):
template_name = 'accounts/inner_index.html'
class Create_Organisation(CreateView):
model = models.Organisation
fields = ('__all__')
template_name = 'accounts/organisation_form.html'
success_url = reverse_lazy("accounts:inner_index")
class Create_Accounts(CreateView,LoginRequiredMixin):
model = models.MyUser
form_class = forms.MyUserForm
template_name = 'accounts/create_account.html'
success_url = reverse_lazy("accounts:inner_index")
class LoginPageView(View):
template_name = 'accounts/login_account.html'
form_class = forms.MyUserLoginForm
def get(self, request):
form = self.form_class()
message = ''
return render(request, self.template_name, context={'form': form, 'message': message})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
email = form.cleaned_data['email'],
password=form.cleaned_data['password'],
organisation = form.cleaned_data['organisation'],
)
if user:
login(request, user)
return redirect('/accounts/')
message = 'Login failed!'
return render(request, self.template_name, context={'form': form, 'message': message})
#urls.py
app_name = "accounts"
urlpatterns = [
path('',views.indexPage.as_view(),name = 'inner_index'),
path('create_organisation/',views.Create_Organisation.as_view(),name='create_organisation'),
path('create_account/',views.Create_Accounts.as_view(),name='create_account'),
path('login_account/',views.LoginPageView.as_view(),name = 'login'),
path('login_test/',views.Login_Test.as_view(),name='login_test'),
]
#login_account.html
{% extends 'base.html' %}
{% load bootstrap3 %}
{% block body_block %}
<form method="POST">
<h1>LOGIN</h1>
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" name="" value="Login">
</form>
{% endblock %}
#settings.py
AUTH_USER_MODEL = 'accounts.MyUser'
LOGIN_REDIRECT_URL = '/accounts/login_account'
您的代码中有一个主要问题。也就是说,通过使用通用
CreateView
来创建用户,它不会使用您的经理,因此不会散列密码,因此您需要覆盖它:
views.py
class Create_Accounts(CreateView,LoginRequiredMixin):
model = models.MyUser
form_class = forms.MyUserForm
template_name = 'accounts/create_account.html'
success_url = reverse_lazy("accounts:inner_index")
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
self.model.objects.create_user(**form.cleaned_data)
return redirect('accounts:login')
但是,您的主要问题是因为您正在尝试使用登录数据验证表单,这就是您得到
username already exists
的原因。因为 ModelForm
会尝试验证 username
,这应该是通过 `unique:
models.py(片段)
class MyUser(AbstractBaseUser):
username = models.CharField(max_length=256,unique=True)
...
此外,默认身份验证不需要
organisation
和 email
backend
(该表单对于轻松渲染组件仍然有用):
views.py
class LoginPageView(View):
...
def get(self, request):
...
def post(self, request):
credentials = {
'username': request.POST.get('username'),
'password': request.POST.get('password')
}
user = authenticate(**credentials)
if user:
login(request, user)
return redirect('/accounts/')
message = 'Login failed!'
return render(request, self.template_name, context={'message': message})
你好,我已经尝试解决这个问题 3 天了,我终于做到了,问题出在你的 forms.py 中,即:
class MyUserForm(forms.ModelForm):
class Meta():
model = models.MyUser
fields = ('username','email','password','organisation')
在此表单中,您使用“Class Meta”,这是导致验证错误的原因,您会注意到您的 python 代码将始终停止在
If form.is_valid():
处,因为您的表单无效。您遇到的问题是由于 CustomUser 模型的约束(例如唯一用户名或其他字段约束)与表单的身份验证使用冲突造成的。
我所做的只是一个简单的表格:
class CustomUserAuthenticationForm(forms.Form):
username = forms.CharField(max_length=150)
password = forms.CharField(widget=forms.PasswordInput)
我在这个特定的代码片段中没有使用 Meta 类的原因是它是一个简单的 Form,而不是 ModelForm。 Meta 类通常在 ModelForm 中用于指定有关表单与模型关系的元数据,例如模型本身、要包含/排除的字段等。如果此表单与 Django 模型相关并打算用作该模型的 ModelForm model、Meta 类对于定义模型、字段或与模型-表单关联相关的其他元数据等内容是必要的。但对于不依赖于模型的独立表单,直接在类中定义字段就足够了。