[Answered ]-Form.get_user() returning None in Django

1👍

Because the get_user() method only returns the user_cache. Indeed, in the source code [GitHub], we see:

def get_user(self):
     return self.user_cache

The user_cache is set to None in the constructor, and populated with the user, if the credentials match in the clean method:

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')

        if username is not None and password:
            self.user_cache = authenticate(self.request, username=username, password=password)
            if self.user_cache is None:
                raise self.get_invalid_login_error()
            else:
                self.confirm_login_allowed(self.user_cache)

        return self.cleaned_data

This clean() method is triggered when you can .is_valid(), since then the form will first validate the fields, and then clean the fields, and eventually clean the entire object. Indeed, if we look at the source code of the Form class [GitHub], we see:

@property
def errors(self):
    """Return an ErrorDict for the data provided for the form."""
    if self._errors is None:
        self.full_clean()
    return self._errors

def is_valid(self):
    """Return True if the form has no errors, or False otherwise."""
    return self.is_bound and not self.errors

The .is_valid() method thus will obtain the .errors property, and this will trigger a full_clean() that will populate the user_cache.

It is also sensical to first validate a form, and only when the form is valid provide a user.

Leave a comment