如何在 django 忘记密码中添加 "search by usernane or email address" 字段

how to add "search by usernane or email address" field in django forgot password

这是 django 默认的忘记密码表单。如何修改以添加 "search by username" 功能。例如 "username/email"。有人可以帮我弄这个吗。我是 django 的菜鸟。刚开始学习。

def get_users(self, email):

    active_users = UserModel._default_manager.filter(**{
        '%s__iexact' % UserModel.get_email_field_name(): email,
        'is_active': True,
    })
    return (u for u in active_users if u.has_usable_password())

def save(self, domain_override=None,
         subject_template_name='registration/password_reset_subject.txt',
         email_template_name='registration/password_reset_email.html',
         use_https=False, token_generator=default_token_generator,
         from_email=None, request=None, html_email_template_name=None,
         extra_email_context=None):
    """
    Generate a one-use only link for resetting password and send it to the
    user.
    """
    email = self.cleaned_data["email"]
    for user in self.get_users(email):
        if not domain_override:
            current_site = get_current_site(request)
            site_name = current_site.name
            domain = current_site.domain
        else:
            site_name = domain = domain_override
        context = {
            'email': email,
            'domain': domain,
            'site_name': site_name,
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'user': user,
            'token': token_generator.make_token(user),
            'protocol': 'https' if use_https else 'http',
            **(extra_email_context or {}),
        }
        self.send_mail(
            subject_template_name, email_template_name, context, from_email,
            email, html_email_template_name=html_email_template_name,
        )

我们可以在电子邮件字段和 username 字段中搜索 Q objects [Django-doc]:

from django.db.models import <b>Q</b>

def get_users(self, email):
    active_users = UserModel._default_manager.filter(
        <b>Q(**{</b>'%s__iexact' % UserModel.get_email_field_name(): email<b>}) |</b>
        <b>Q(username=email)</b>,
        is_active=True
    )
    return (u for u in active_users if u.has_usable_password())

您可以将 __iexact field lookup [Django-doc] 添加到用户名,因此 username__iexact=email 如果您想以 敏感的方式搜索用户名。

save 函数中,您可能应该改用用户的 email

def save(self, domain_override=None,
         subject_template_name='registration/password_reset_subject.txt',
         email_template_name='registration/password_reset_email.html',
         use_https=False, token_generator=default_token_generator,
         from_email=None, request=None, html_email_template_name=None,
         extra_email_context=None):
    """
    Generate a one-use only link for resetting password and send it to the
    user.
    """
    email = self.cleaned_data["email"]
    for user in self.get_users(email):
        if not domain_override:
            current_site = get_current_site(request)
            site_name = current_site.name
            domain = current_site.domain
        else:
            site_name = domain = domain_override
        <b>email = getattr(user, UserModel.get_email_field_name())</b>
        context = {
            'email': email,
            'domain': domain,
            'site_name': site_name,
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'user': user,
            'token': token_generator.make_token(user),
            'protocol': 'https' if use_https else 'http',
            **(extra_email_context or {}),
        }
        self.send_mail(
            subject_template_name, email_template_name, context, from_email,
            email, html_email_template_name=html_email_template_name,
        )