首页 > 解决方案 > django 中的自定义用户模型以使用电话和电子邮件进行注册

问题描述

默认情况下,django 使用 USERNAME_FIELD 进行身份验证,但它只需要一个字段。但我希望我的注册表单允许用户使用电话号码或电子邮件进行注册,就像在 facebook 中发生的那样。任何人都可以帮助我如何实现这一目标?

标签: djangomodel

解决方案


首先,您的 phone_number 字段应该是唯一的,您必须为此创建一个自定义后端并在设置中注册,后端通过用户名或 phone_number 检查用户,然后检查用户的密码,如果凭据正确,则登录用户。例如,

#backends.py
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q

from django.contrib.auth import get_user_model

User = get_user_model()

class UserNamePhoneAuthBackend(ModelBackend):
    """UserName or Phone Authentication Backend.

    Allows user sign in with email or phone then check password is valid
    or not and return user else return none
    """

    def authenticate(self, request, username_or_phone=None, password=None, role=None):
        try:
            user = User.objects.get(
                (Q(username=username_or_phone) | Q(phone_number=username_or_phone)))
        except ObjectDoesNotExist:
            return None
        else:
            if user.check_password(password):
                return user
            else:
                return None

    def get_user(self, user_id):
        try:
            return CustomUser.objects.get(id=user_id)
        except ObjectDoesNotExist:
            return None

#settings

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "path.for.UserNamePhoneAuthBackend",
)
#views.py
from django.contrib.auth import authenticate
from django.contrib.auth import login
class UserLogin(ApiView):
  def post(self, request):
    username_or_phone = request.data.get("username_or_phone")
    password = request.data.get("password")
    user = authenticate(
            username_or_phone=username_or_phone,
            password=password)
    if user is not None:
     login(user)
    # return token for user
    else:
     return Response("Invalid Credentials")
     

推荐阅读