重写 AuthenticationForm 中的 Clean 方法后,身份验证将返回 None,并且不处理任何错误



friend.

在用户登录之前,需要重写AuthenticationForm中的Сlean方法,以进一步检查是否存在属性。

Forms.py:

from django.contrib.auth.forms import AuthenticationForm as BaseAuthenticationForm
from django.contrib.auth.models import User
from inc.models import Account, UserProfile, Counter
class AuthenticationForm(BaseAuthenticationForm):
def clean(self):
username = self.cleaned_data.get('username')
user = User.objects.filter(username = username).first()
if user != None:
print(user)
if not user.is_superuser and not user.is_staff:
account = Account.objects.filter(num_account = UserProfile.objects.filter(user__username = username).first().num_account).first()
have_counter = Counter.objects.filter(num_account = account).all()
if not have_counter:
raise forms.ValidationError('Some text...')
return self.cleaned_data

Views.py:

from django.contrib.auth import login, authenticate
from .forms import AuthenticationForm
def LogIn(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
print(user)
login(request, user)
return redirect('/')
else:
print(form.errors)
else:
form = AuthenticationForm()
return render(request, 'userprocessing/login.html', {'form': form})

问题如下。当我尝试注册为数据库中的用户时,一切都可以正常工作,但是当我输入不存在的登录名时,我会抛出:

AnonymousUser' object has no attribute '_meta'

这指向login(request, user).该错误是可以理解的,它无法登录不返回user = authenticate(username=username, password=password)的用户(它返回None(。

问题是为什么它不处理错误,必须有一条消息检查用户名或密码。

也许我没有正确重新定义CleanAuthenticationForm方法?

上级:

追踪:

Request Method: POST
Request URL: http://localhost:8000/login/?next=/
Django Version: 2.0.5
Python Version: 3.6.5
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'inc.apps.IncConfig',
'main.apps.MainConfig',
'django.contrib.admin']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback:
File "...PythonPython36-32libsite-packagesdjangocorehandlersexception.py" in inner
35.             response = get_response(request)
File "...PythonPython36-32libsite-packagesdjangocorehandlersbase.py" in _get_response
128.                 response = self.process_exception_by_middleware(e, request)
File "...PythonPython36-32libsite-packagesdjangocorehandlersbase.py" in _get_response
126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "...views.py" in LogIn
57.             login(request, user)
File "...PythonPython36-32libsite-packagesdjangocontribauth__init__.py" in login
155.     request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
File "...PythonPython36-32libsite-packagesdjangoutilsfunctional.py" in inner
216.         return func(self._wrapped, *args)
Exception Type: AttributeError at /login/
Exception Value: 'AnonymousUser' object has no attribute '_meta'

在您的clean方法中,您仅在用户存在但不是超级用户或员工的情况下引发错误。

当用户根本不存在时,您还应该引发错误。

我会使用 try 来做到这一点,除了,否则。

def clean(self):
cleaned_data = super().clean()
username = cleaned_data.get('username')
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise forms.ValidationError('User does not exist...')
else:
print(user)
if not user.is_superuser and not user.is_staff:
account = Account.objects.filter(num_account=UserProfile.objects.filter(user__username=username).first().num_account).first()
have_counter = Counter.objects.filter(num_account=account).all()
if not have_counter:
raise forms.ValidationError('Some text...')
return cleaned_data

附言。我没有检查你的干净方法的逻辑,除了 用户是否存在。

查看 Django 关于验证表单的文档。还有关于为什么你应该在你被覆盖的clean()内称超级。

  • 重写 clean(( 方法
  • 表单和字段验证

最新更新