django-allauth
django-allauth copied to clipboard
The is_active field is not guaranteed to be present on custom user models
We use a custom user model derived directly from AbstractBaseUser
and PermissionsMixin
in our application. Our model does not have the is_active
field. We use a different field for the same purpose and is_active
is just a property.
Therefore we're getting the following error when using the password reset form:
FieldError: Related Field got invalid lookup: is_active
...
File "allauth/account/views.py", line 101, in post
if form.is_valid():
File "django/forms/forms.py", line 175, in is_valid
return self.is_bound and not self.errors
File "django/forms/forms.py", line 170, in errors
self.full_clean()
File "django/forms/forms.py", line 372, in full_clean
self._clean_fields()
File "django/forms/forms.py", line 393, in _clean_fields
value = getattr(self, 'clean_%s' % name)()
File "allauth/account/forms.py", line 525, in clean_email
self.users = filter_users_by_email(email, is_active=True)
File "allauth/account/utils.py", line 425, in filter_users_by_email
mails = mails.filter(user__is_active=is_active)
File "django/db/models/query.py", line 941, in filter
return self._filter_or_exclude(False, args, kwargs)
File "django/db/models/query.py", line 961, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "django/db/models/query.py", line 968, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "django/db/models/sql/query.py", line 1391, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "django/db/models/sql/query.py", line 1410, in _add_q
child_clause, needed_inner = self.build_filter(
File "django/db/models/sql/query.py", line 1345, in build_filter
condition = self.build_lookup(lookups, col, value)
File "django/db/models/sql/query.py", line 1182, in build_lookup
raise FieldError('Related Field got invalid lookup: {}'.format(lookup_name))
It appears that the filter_users_by_email
function is the root of the problem. I propose the following change to the function:
def filter_users_by_email(email, is_active=None):
from .models import EmailAddress
User = get_user_model()
mails = EmailAddress.objects.filter(email__iexact=email)
users = []
for e in mails.prefetch_related("user"):
if _unicode_ci_compare(e.email, email):
users.append(e.user)
if app_settings.USER_MODEL_EMAIL_FIELD:
q_dict = {app_settings.USER_MODEL_EMAIL_FIELD + "__iexact": email}
user_qs = User.objects.filter(**q_dict)
for user in user_qs.iterator():
user_email = getattr(user, app_settings.USER_MODEL_EMAIL_FIELD)
if _unicode_ci_compare(user_email, email):
users.append(user)
if is_active is not None:
return [u for u in set(users) if u.is_active == is_active]
return list(set(users))
Even though it theoretically makes the whole DB query less effective (we can be fetching more DB records than needed), it shouldn't be a problem in real world as there probably won't be many user accounts using the same email address.
Makes sense. Can you send over a pull request?
@operutka how were you able to bypass this any suggestion on how I can go about this I am having the same problem... I do not know how to temporarily resolve this any idea or help please
@pennersr can you please look into this proposed solution
Ran into this issue today, tested the proposed code and it behaves as expected. @pennersr or @operutka Do you need/want me to submit the pull request to move this forward?
Yes, as mentioned, a pull request would be appreciated.
@pennersr,can i add this?
Closed via 7e516bc3