После переопределения метода Clean в AuthenticationForm, authenticate возвращает None и не обрабатывает никаких ошибок. - PullRequest
0 голосов
/ 06 июня 2018

друг.

Необходимо было переопределить метод Сlean в AuthenticationForm, чтобы дополнительно проверить наличие атрибута, прежде чем пользователь сможет войти в систему.

Формы.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:

Traceback:

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'

1 Ответ

0 голосов
/ 06 июня 2018

В вашем методе 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 о проверке форм.Также о том, почему вы должны вызывать super внутри вашего переопределенного clean().

...