Search code examples
pythondjangodecoratordjango-authentication

Django 'User' object has no attribute 'user' when combining login_required with user_passes_test


I'm trying to combine a custom user_passes_test with a login_required decorator.

This works fine:

@login_required
@user_passes_test(profile_expired, "Main:profile_expired")
def home(request):
    return render(request, "Main/pages/home.html", {})

In helpers.py

def profile_expired(user):
    if user.is_authenticated and user.profile.expiration_date is not None:
        return user.profile.expiration_date >= date.today()
    elif user.profile.expiration_date is None:
        return True
    return False

If I visit /app/ and profile_expired returns True, I get redirected to /app/profile_expired.

However, the very same code on all other views, is returning error...

@login_required
@user_passes_test(profile_expired, "Main:profile_expired")
def another_view(request):
    # some code...
    return render(request, "Main/pages/another_page.html", context)

Error:

Traceback (most recent call last):
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\contrib\auth\decorators.py", line 20, in _wrapped_view
    if test_func(request.user):
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\contrib\auth\decorators.py", line 20, in _wrapped_view
    if test_func(request.user):
  File "C:\Users\S\PycharmProjects\SO\venv\lib\site-packages\django\utils\functional.py", line 257, in inner
    return func(self._wrapped, *args)
AttributeError: 'User' object has no attribute 'user'

While home has just the code above, another_view (and all other views) have more code... But the error cannot be inside the view since I've placed a breakpoint inside of them, started the debugger, and they never get triggered. The error must be somewhere else.

I can't pinpoint why is this happening. Any idea?


Solution

  • The test_func should take a user as its argument.

    def profile_expired(user):
        return user.profile.expiry_date > date.today()
    

    You haven't shown your function, but I suspect that you have written it to take a request, then use request.user.

    def profile_expired(request):
        return request.user.profile.expiry_date > date.today()