使用电子邮件或电话号码登录 Django

Nah*_*doy 2 python authentication django django-models django-rest-framework

很长一段时间以来,我一直在尝试寻找 Django 中问题的解决方案。问题是我正在尝试开发一个登录系统,可以使用电子邮件或电话号码来验证用户身份。

小智 11

好吧,这可以通过创建自定义用户模型来完成。我已经测试过了。有用。

第一步

您需要做的第一件事是创建一个新的 Django 项目。确保您不运行迁移,因为在此之前我们还需要做一些事情。

创建新的 Django 项目后,使用以下命令创建一个名为accounts 的新应用程序:

python manage.py startapp accounts
Run Code Online (Sandbox Code Playgroud)

创建用户模型

默认情况下,Django 提供的用户模型有一个用户名字段和一个电子邮件字段。但是,我们还需要一个电话号码字段。为了添加这个字段,我们需要扩展 Django 用户模型。在帐户应用程序的models.py文件中,输入以下代码:

模型.py

python manage.py startapp accounts
Run Code Online (Sandbox Code Playgroud)

向管理员注册模型

管理员.py

phone_validator = RegexValidator(r"^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$", "The phone number provided is invalid")


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=100, unique=True)
    phone_number = models.CharField(max_length=16, validators=[phone_validator], unique=True)
    full_name = models.CharField(max_length=30)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    # is_translator = models.BooleanField(default=False)
    objects = CustomUserManager()
    USERNAME_FIELD = 'phone_number'
    REQUIRED_FIELDS = ['email', 'full_name']

    def __str__(self):
        return self.email

    @staticmethod
    def has_perm(perm, obj=None, **kwargs):
        return True

    @staticmethod
    def has_module_perms(app_label, **kwargs):
        return True

    @property
    def is_staff(self):
        return self.is_admin
Run Code Online (Sandbox Code Playgroud)

表格.py

class UserAdmin(BaseUserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm
    list_display = ('email', 'phone_number', 'full_name', 'is_active', 'is_admin')
    list_filter = ('is_active', 'is_admin')
    fieldsets = (
        (None, {'fields': ('full_name', 'email', 'phone_number', 'password')}),
        ('Permissions', {'fields': ('is_active', 'is_admin', 'is_superuser', 'last_login', 'groups', 'user_permissions')}),
    )
    add_fieldsets = (
        (None, {'fields': ('full_name', 'phone_number', 'email', 'password1', 'password2')}),
    )
    search_fields = ('email', 'full_name')
    ordering = ('email',)
    filter_horizontal = ('groups', 'user_permissions')

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        is_superuser = request.user.is_superuser
        if is_superuser:
            form.base_fields['is_superuser'].disabled = True
        return form

    admin.site.register(User, UserAdmin)
Run Code Online (Sandbox Code Playgroud)

对于登录客户login.html

视图.py

class UserLoginForm(forms.Form):
    email = forms.CharField(max_length=50)
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control'}))
Run Code Online (Sandbox Code Playgroud)

编写自定义后端

后端.py

import random
from .backends import EmailPhoneUsernameAuthenticationBackend as EoP

class UserLoginView(View):
    form_class = UserLoginForm
    template_name = 'accounts/login.html'

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect('core:home')
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        form = self.form_class
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = EoP.authenticate(request, username=cd['email'], password=cd['password'])
            if user is not None:
                login(request, user)
                messages.success(request, 'You have successfully logged in!', 'success')
                return redirect('core:home')
            else:
                messages.error(request, 'Your email or password is incorrect!', 'danger')
        return render(request, self.template_name, {'form': form})
Run Code Online (Sandbox Code Playgroud)

更新设置(3 个选项)

设置.py

INSTALLED_APPS = [
...
# Third-party apps
'accounts.apps.AccountsConfig',
...
]

AUTH_USER_MODEL = 'accounts.User'

AUTHENTICATION_BACKENDS = [
'accounts.backends.EmailPhoneUsernameAuthenticationBackend'
]
Run Code Online (Sandbox Code Playgroud)

我希望您的问题能够得到解决,并且其他人也能使用它。