Uri
Uri

Reputation: 3301

Can I safely use `self.request.user.is_authenticated` in views?

We are using Django 2.1 for Speedy Net. There is a view which I want to be different for admin (staff) than for regular users. I added the following (3 first) lines to the code:

def get_user_queryset(self):
    if (self.request.user.is_authenticated):
        if ((self.request.user.is_staff) and (self.request.user.is_superuser)):
            return User.objects.get_queryset()
    return User.objects.active()

But the problem is, one of the tests fails with an error message:

AttributeError: 'WSGIRequest' object has no attribute 'user'

(link) And I want to know - Is it safe to use self.request.user.is_authenticated in views? Should I fix the test to work or can my code fail in production? The test uses RequestFactory(), is there a problem with RequestFactory() not containing attribute 'user'? Or is there a problem with my code which may also fail in production?

If I should fix the test, how do I do it? Here is the code of the test which fails:

class UserMixinTextCaseMixin(object):
    def set_up(self):
        super().set_up()
        self.factory = RequestFactory()
        self.user = ActiveUserFactory(slug='look-at-me', username='lookatme')
        self.other_user = ActiveUserFactory()

    def test_find_user_by_exact_slug(self):
        view = UserMixinTestView.as_view()(self.factory.get('/look-at-me/some-page/'), slug='look-at-me')
        self.assertEqual(first=view.get_user().id, second=self.user.id)

By the way, I'm not sure what is the purpose of slug='look-at-me' in the view = ... line of the test?

Upvotes: 0

Views: 1387

Answers (2)

Uri
Uri

Reputation: 3301

I found out this answer on Stack Overflow.

From the docs:

    # Recall that middleware are not supported. You can simulate a
    # logged-in user by setting request.user manually.
    request.user = self.user

    # Or you can simulate an anonymous user by setting request.user to
    # an AnonymousUser instance.
    request.user = AnonymousUser()

Adding request.user = AnonymousUser() in the tests solves the problem:

class UserMixinTextCaseMixin(object):
    def set_up(self):
        super().set_up()
        self.factory = RequestFactory()
        self.user = ActiveUserFactory(slug='look-at-me', username='lookatme')
        self.other_user = ActiveUserFactory()

    def test_find_user_by_exact_slug(self):
        request = self.factory.get('/look-at-me/some-page/')
        request.user = AnonymousUser()
        view = UserMixinTestView.as_view()(request=request, slug='look-at-me')
        self.assertEqual(first=view.get_user().id, second=self.user.id)

Replacing MIDDLEWARE with MIDDLEWARE_CLASSES doesn't solve the problem and we are already using 'django.contrib.auth.middleware.AuthenticationMiddleware', but this is not used by RequestFactory().

Upvotes: 0

JPG
JPG

Reputation: 88569

Yeah... It's safe to use request.user or self.request.user in Django and it is the Django way of checking whether the User is authenticated or not.

AttributeError: 'WSGIRequest' object has no attribute 'user'

Django assigning the authenticated user to the request object within the Django Middleware execution, specifically within the AuthenticationMiddleware class (source-code of AuthenticationMiddleware class).


So, adding the AuthenticationMiddleware class to the Middleware settings or creating your own middleware class is will solve the AttributeError: 'WSGIRequest' object has no attribute 'user' error.

Upvotes: 1

Related Questions