的朋友。
需要覆盖Сlean
中的AuthenticationForm
方法,以便在用户登录之前进一步检查是否存在属性。
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
)。
问题是它为什么不处理错误,必须有消息检查用户名或密码。
也许我没有正确地重新定义Clean
中的AuthenticationForm
方法?
UPD:
回溯:
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 "...\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
35. response = get_response(request)
File "...\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "...\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "...\views.py" in LogIn
57. login(request, user)
File "...\Python\Python36-32\lib\site-packages\django\contrib\auth\__init__.py" in login
155. request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
File "...\Python\Python36-32\lib\site-packages\django\utils\functional.py" in inner
216. return func(self._wrapped, *args)
Exception Type: AttributeError at /login/
Exception Value: 'AnonymousUser' object has no attribute '_meta'
答案 0 :(得分:0)
在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
PS。我没有检查你的干净方法的逻辑除外 用户是否存在。
检查Django关于验证表单的文档。另外还有为什么你应该在被覆盖的clean()
内调用超级。