Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NotImplementedError: Django doesn't provide a DB representation for AnonymousUser

I get the following error:

Traceback:

 File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\exception.py" 
 in inner
 35.             response = get_response(request)

 File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\base.py" in 
  _get_response
  128.                 response = self.process_exception_by_middleware(e, 
 request)

 File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\base.py" in 
 _get_response
 126.                 response = wrapped_callback(request, *callback_args, 
 **callback_kwargs)

  File "C:\Users\HP\Desktop\erpcloud\accounts\views.py" in change_password
   31.         if form.is_valid():

 File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in is_valid
 179.         return self.is_bound and not self.errors

File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in errors
 174.             self.full_clean()

 File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in 
 full_clean
  376.         self._clean_fields()

 File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in 
_clean_fields
 397.                     value = getattr(self, 'clean_%s' % name)()

  File "C:\Users\HP\GST\lib\site-packages\django\contrib\auth\forms.py" in 
 clean_old_password
  366.         if not self.user.check_password(old_password):

 File "C:\Users\HP\GST\lib\site-packages\django\contrib\auth\models.py" in 
 check_password
  396.         raise NotImplementedError("Django doesn't provide a DB 
  representation for AnonymousUser.")

  Exception Type: NotImplementedError at /accounts/change-password/
   Exception Value: Django doesn't provide a DB representation for 
  AnonymousUser.

My view looks like this:

def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(data=request.POST, user=request.user)

        if form.is_valid():
            form.save()
            update_session_auth_hash(request, user)
            return redirect(reverse('company:Dashboard'))
        else:
            return redirect(reverse('accounts:change_password'))
    else:
        form = PasswordChangeForm(user=request.user)

        args = {'form': form}
        return render(request, 'accounts/change_password.html', args)

Firstly, I thought that this was due to the fact that I didn't have Django updated, but now I have, and I receive the same error.

I've looked at some solutions that other users asked, but none applied in my case

Any help, please ?

like image 885
Niladry Kar Avatar asked Mar 05 '23 11:03

Niladry Kar


1 Answers

There is nothing wrong with the view itself. The problem is that if a user is not logged in, then request.user will point to a AnonymousUser object. You can see it as a virtual user. This user however has no database representation, since we do not know anything about the user. It is more used to provide a uniform interface.

Now since request.user is an AnonymousUser, you aim to change the password of that user, but you can not store that into a database, hence the error.

The user thus first needs to log in, then request.user will be a real user, and updating the password should work.

I advise however to add a @login_required decorator to the view to prevent this scenario from happening:

from django.contrib.auth.decorators import login_required

@login_required
def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(data=request.POST, user=request.user)

        if form.is_valid():
            form.save()
            update_session_auth_hash(request, user)
            return redirect(reverse('company:Dashboard'))
        else:
            return redirect(reverse('accounts:change_password'))
    else:
        form = PasswordChangeForm(user=request.user)

        args = {'form': form}
        return render(request, 'accounts/change_password.html', args)
like image 160
Willem Van Onsem Avatar answered Apr 06 '23 03:04

Willem Van Onsem