1

I want to use Djangos' built-in LoginView. It works fine until I login a user with a correct password (If the password is wrong it works). Then I get this error:

'AnonymousUser' object has no attribute '_meta'

I already added AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend'] to my settings.py and I looked at Django login AttributeError: 'AnonymousUser' object has no attribute '_meta' and on other webpages but they couldn't help me.

MIDDLEWARE = [
     # Must have middlewares
    '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',
    'simple_history.middleware.HistoryRequestMiddleware',
    'admin_reorder.middleware.ModelAdminReorder',

    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',

     # Custom middlewares
    'utils.Middleware.RangesMiddleware.RangesMiddleware',
    'utils.Middleware.AdminAccessMiddleware.AdminAccessMiddleware',
    'apps.log_request.middlewares.RequestLogMiddleware',
]

.

Internal Server Error: /auth/anmelden
Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Program Files\Python37\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\decorators.py", line 142, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\decorators.py", line 45, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\views\decorators\debug.py", line 76, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\decorators.py", line 45, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\decorators.py", line 142, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\decorators.py", line 45, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\contrib\auth\views.py", line 61, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\django\views\generic\edit.py", line 142, in post
    return self.form_valid(form)
  File "C:\Program Files\Python37\lib\site-packages\django\contrib\auth\views.py", line 90, in form_valid
    auth_login(self.request, form.get_user())
  File "C:\Program Files\Python37\lib\site-packages\django\contrib\auth\__init__.py", line 126, in login
    request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
  File "C:\Program Files\Python37\lib\site-packages\django\utils\functional.py", line 257, in inner
    return func(self._wrapped, *args)
AttributeError: 'AnonymousUser' object has no attribute '_meta'
[05/Jun/2019 21:25:28] "POST /auth/anmelden HTTP/1.1" 500 159900

This error occurs on \django\utils\decorators.py in line 142 (response = view_func(request, *args, **kwargs)) (I used PyCharm to debug). My middleware is: <django.middleware.csrf.CsrfViewMiddleware object at 0x000002105D119470> and my view_func is functools.partial(<bound method LoginView.dispatch of <django.contrib.auth.views.LoginView object at 0x000002105F768C50>>).

My path in my urls.py:

path('anmelden', LoginView.as_view(
        template_name="authenticate/login.html",
        authentication_form=SignInForm,
        extra_context={
            "selected": "authenticate",
            "title": title_suffix("Anmelden", Config.verbose_name),
        },
    ), name="login"),

My clean function in my SignInForm:

def clean(self):
    User.remove_expired_user()

    cleaned_data = self.cleaned_data # That's the error. I had to use self.clean()!!!!
    username = cleaned_data.get("username")
    password = cleaned_data.get("password")

    if "@" in username:
        try:
            username = User.objects.get(email__iexact=username).username
        except ObjectDoesNotExist:
            raise forms.ValidationError("Diese E-Mail-Adresse wurde nicht gefunden")
    else:
        try:
            username = User.objects.get(username=username).username
        except ObjectDoesNotExist:
            raise forms.ValidationError("Dieser Benutzername wurde nicht gefunden")

    user = authenticate(username=username, password=password)

    if user is None:
        try:
            us = User.objects.get(username=username)
        except ObjectDoesNotExist:
            pass
        else:
            if us.check_password(password) and not us.is_active:
                raise forms.ValidationError("Dieser Account ist deaktiviert. Du kannst ihn über deine E-Mail aktivieren.")
        raise forms.ValidationError("Falsches Passwort")
    return cleaned_data

I FOUND THE ERROR:

In my clean function I used self.cleaned_data instead of self.clean().

Myzel394
  • 1,155
  • 3
  • 16
  • 40
  • You added ```LoginView.as_view()``` in urls.py ? – gachdavit Jun 05 '19 at 18:28
  • @gachdavit Yes I added. – Myzel394 Jun 05 '19 at 19:28
  • The setting `AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend']` is the default, so that doesn't do anything. I wonder why the user is an AnonymousUser while you say that the user exists in the database. I don't know how to solve it, but I would look into that direction. – physicalattraction Jun 10 '19 at 09:59
  • @Myzel394 can you please share your codes of RequestLogMiddleware, AdminAccessMiddleware, RangesMiddleware please? – ruddra Jun 11 '19 at 05:30
  • @ruddra I don't want to do that because they contain sensitive code (that shouldn't be public). AdminAccessMiddleware just checks whether the user is verified to access the admin panel. I copied `RangesMiddleware` from https://stackoverflow.com/a/35928017/9878135. RequestLogMiddleware logs all requests into the database. I already tried to login without these Middlewares but it didn't change anything. – Myzel394 Jun 11 '19 at 17:35
  • What's your `settings.AUTH_USER_MODEL`? `ModelBackend` has a docstring of "Authenticates against settings.AUTH_USER_MODEL." and `settings.AUTH_USER_MODEL` is the class that gets created on authentication. – Eric Ihli Jun 12 '19 at 00:12
  • @EricIhli I haven't defined `AUTH_USER_MODEL`. – Myzel394 Jun 12 '19 at 19:55
  • @Myzel394 are you sure you passing user in request? (cookies, token or whatever) – Igor Belkov Jun 14 '19 at 14:42
  • @IgorBelkov Yes when I debug it I can see that request is not None. It also has the attribute `POST` with the values I typed in. `args` and `kwargs` are empty. – Myzel394 Jun 14 '19 at 20:21

1 Answers1

0

Find the directory on your computer where Django is getting loaded from.

python -c "import sys; print([p for p in sys.path if 'site-packages' in p])"

Open that directory and find django. Insert an import pdb; pdb.set_trace() at https://github.com/django/django/blob/a8e2a9bac6e548d6ab2e13af6171d2fdd3b8055b/django/contrib/auth/init.py#L72 and step through inspecting each step along the way. Somewhere in that process, you should get to a point where you're expecting a User model but getting an AnonymousUser model. Once you find that point, it will be easier to figure out the "why" behind it.

Eric Ihli
  • 1,722
  • 18
  • 30
  • This should be a comment, not an answer. – hoefling Jun 13 '19 at 08:45
  • Ok thank you. I Inserted this **before** `user = backend.authenticate(request, **credentials)`. When I try to login I get this message: `> c:\program files\python37\lib\site-packages\django\contrib\auth\__init__.py(75)authenticate() -> user = backend.authenticate(request, **credentials) (Pdb) ` and Django freezes. Is this correct or did I break anything? – Myzel394 Jun 13 '19 at 15:07
  • That's expected. When that happens, you should be able to type in the terminal where it says `(Pdb)`. You can type `h` and press Enter and see a list of available commands. `n` will run the line you're currently on and move to the next line. `s` will "step" into the function call of the line you're currently on. So from where you are, you can type `s` and press Enter and you'll be inside `backend.authenticate`. Type `self` and press enter and it will evaluate `self` and print it to the terminal. Make sure `self` is the backend you expect (`django.contrib.auth.backends.ModelBackend`). – Eric Ihli Jun 13 '19 at 15:53
  • Continue "stepping" and "nexting" and evaluating python code at each line until you find the issue. The command `l` will come in handy to view several lines of context around the line you're on. @hoefling, noted. I thought the "how to figure out the answer" more valuable than the answer itself, and I felt confident this step would lead quite directly to the answer for not only Myzel's case but for people getting the same error but from slightly different causes. In hindsight, you're probably right though. This isn't technically an answer. – Eric Ihli Jun 13 '19 at 15:58
  • I think I found the error. When Django calls `form.get_user()` in `c:\program files\python37\lib\site-packages\django\contrib\auth\views.py(90)form_valid()` it returns None. So this is a problem from Django isn't it? `> c:\program files\python37\lib\site-packages\django\contrib\auth\views.py(90)form_valid()->None -> auth_login(self.request, form.get_user()) (Pdb) auth_login(self.request, form.get_user()) *** AttributeError: 'AnonymousUser' object has no attribute '_meta' (Pdb) form.get_user() (Pdb) form.get_user() (Pdb) print(form.get_user()) None` – Myzel394 Jun 13 '19 at 17:41