下面是详细的攻略。
1. 安装依赖库
首先需要安装 django
、django-rest-framework
和 django-rest-framework-simplejwt
这三个库。可以通过以下命令进行安装:
pip install django django-rest-framework django-rest-framework-simplejwt
2. 创建用户模型
在 models.py
文件中创建用户模型,模型中包含手机号和密码两个字段。可以使用 AbstractBaseUser
和 BaseUserManager
实现自定义用户模型,代码如下:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, phone_number, password=None, **extra_fields):
if not phone_number:
raise ValueError('Phone number must be set')
user = self.model(phone_number=phone_number, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, phone_number, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(phone_number, password, **extra_fields)
class CustomUser(AbstractBaseUser):
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(validators=[phone_regex], max_length=17, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = CustomUserManager()
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = []
def __str__(self):
return self.phone_number
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
其中,CustomUserManager
继承 BaseUserManager
。create_user
方法用于创建普通用户,create_superuser
方法用于创建管理员用户。在 CustomUser
中定义手机号(phone_regex
)和密码(password
)两个字段并赋予不同的权限。
3. 创建登录视图
在 views.py
文件中创建登录视图。我们可以使用 APIView
作为基类,通过 serializer
和 jwt
库实现登录功能。代码如下:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import AuthTokenSerializer
class LoginAPIView(APIView):
serializer_class = AuthTokenSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
refresh = RefreshToken.for_user(user)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
})
其中,AuthTokenSerializer
是我们自定义的登录序列化器,用于验证用户。调用 RefreshToken.for_user(user)
生成 JWT 的 token,并将其作为 JSON 格式返回。此处我们只返回了 access_token 和 refresh_token,没有返回 user 信息。
4. 创建登录序列化器
在 serializers.py
文件中创建登录序列化器,用于验证用户输入的手机号和密码,并返回对应的用户信息。代码如下:
from rest_framework import serializers
from django.contrib.auth import authenticate
from .models import CustomUser
class AuthTokenSerializer(serializers.Serializer):
phone_number = serializers.CharField(max_length=500)
password = serializers.CharField(
style={'input_type': 'password'},
trim_whitespace=False
)
def validate(self, attrs):
phone_number = attrs.get('phone_number')
password = attrs.get('password')
user = authenticate(
request=self.context.get('request'),
username=phone_number,
password=password
)
if not user:
raise serializers.ValidationError(
'Invalid phone number or password'
)
attrs['user'] = user
return attrs
其中,CustomUser
是我们自定义的用户模型,authenticate
函数用于验证用户名和密码是否匹配。
5. 添加路由
在 urls.py
文件中添加路由,用于访问登录视图。代码如下:
from django.urls import path
from .views import LoginAPIView
urlpatterns = [
path('login/', LoginAPIView.as_view(), name='login'),
# ... 其他路由
]
示例说明
以下是两条使用手机号登录的实例代码。
示例 1:使用 Postman 发送 POST 请求登录
打开 Postman,选择 POST 请求,将 url
设置为 http://localhost:8000/login/
,在 Body 中传递 JSON 格式的手机号和密码参数:
{
"phone_number": "+1234567890",
"password": "password123"
}
点击 Send,我们会得到如下的返回结果:
{
"refresh": "<token>",
"access": "<token>"
}
其中的 <token>
就是生成的 JWT 的 token。
示例 2:使用 Django Rest Framework 的 API 调用登录
使用 Django Rest Framework 的 API 调用登录,可以通过在 views.py
中创建 TokenObtainPairView
视图来实现,代码如下:
from rest_framework_simplejwt.views import TokenObtainPairView
class CustomTokenObtainPairView(TokenObtainPairView):
serializer_class = CustomTokenObtainPairSerializer
其中,CustomTokenObtainPairSerializer
是自定义的序列化器,用于验证用户输入的手机号和密码。在 urls.py
中添加该视图的路由:
from .views import CustomTokenObtainPairView
urlpatterns = [
# ...
path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
]
使用 API 调用登录的请求示例:
{
"phone_number": "+1234567890",
"password": "password123"
}
返回结果与示例 1 相同。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django项目中使用手机号登录的实例代码 - Python技术站