AtributeError avec un AuthenticationForm
Bonjour,
J'essaie de faire la même chose avec un formulaire qui hérite de AuthenticationForm
Voici le code de ma vue:
def login_user(request):
if request.method == "POST":
form = UserLoginForm(request.POST) # formulaire qui hérite de AuthenticationForm
form.clean() # -> L'erreur est déclenchée par l'appel de cette methode
user = form.get_user()
if user:
login(user)
return redirect("index")
form = UserLoginForm()
return render(request, 'accounts/login.html', context={'form': form})
et voici le traceback:
Traceback (most recent call last):
File "C:\Users\chris\docstring\django\projets\DocShop\.env\Lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\chris\docstring\django\projets\DocShop\.env\Lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\chris\docstring\django\projets\DocShop\src\accounts\views.py", line 24, in login_user
form.clean()
File "C:\Users\chris\docstring\django\projets\DocShop\.env\Lib\site-packages\django\contrib\auth\forms.py", line 198, in clean
username = self.cleaned_data.get('username')
Exception Type: AttributeError at /accounts/login/
Exception Value: 'UserLoginForm' object has no attribute 'cleaned_data'
je comprend pas, parce que cleaned data est hérité de BaseForm ...
Bonjour Christian,
Le problème ici n'a pas rapport avec la classe du formulaire utilisé mais la façon dont on doit valider un formulaire (peu importe le formulaire).
Pour avoir accès au dictionnaire cleaned_data il faut déjà vérifier que le formulaire est valide, avec la méthode is_valid.
Si le formulaire est valide, le dictionnaire cleaned_data associé au formulaire est rempli avec les données valides du formulaires.
La méthode clean est appelé par is_valid et peut être surchargée dans le cas où vous souhaiteriez modifier la vérification du champ d'un formulaire.
Vous pouvez voir le processus détaillé dans la documentation :
https://docs.djangoproject.com/fr/4.1/ref/forms/validation/#form-and-field-validation
Dans votre cas il faudrait plutôt faire :
form = UserLoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
login(request, user)
J'ai éssayé ça :
if form.is_valid():
print(form.cleaned_data)
form.clean()
user = form.get_user()
if user:
login(user)
return redirect("index")
else:
print(form.data)
le problème c'est que je ne rentre pas dans la condition, pourtant je rentre bien un username et un password
ça me print ça:
<MultiValueDict: {}>
Et quand tu affiches le request.POST tu vois bien les données du formulaires ?
Aussi si tu as l'occasion de mettre ton projet sur ton Drive je pourrai regarder plus en détail :)
Bonsoir Christian,
Après pas mal d'essais et de recherches je viens finalement de trouver le problème. Le formulaire AuthenticationForm est effectivement différents des autres formulaires. Le premier argument n'est en effet pas data, celui qui récupère les données de request.POST, mais la requête, ceci pour la gestion des cookies (https://www.janosgyerik.com/django-authenticationform-gotchas/).
Il faut donc initialiser ce formulaire ainsi :
form = UserLoginForm(data=request.POST)
Au lieu de juste :
form = UserLoginForm(request.POST)
On voit en effet la différence dans la méthode init entre le formulaire de base (BaseForm) qui définit data en premier paramètre :
Et AuthenticationForm qui redéfinie la méthode __init__ avec request en premier.
Voilà donc le fin mot de l'histoire ;)
Bonne continuation :) !
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte