Django rest_framework 后端接口开发 开发与用户相关的一组接口 登录注册与用户信息查询修改
Django rest_framework 后端接口開發(fā) 開發(fā)與用戶相關(guān)的一組接口
Django DRF框架用起來還是有一些難度的,需要做的配置,需要導(dǎo)的包很多,所以需要多多練習(xí)才能掌握它的使用。此文記錄了使用Django rest_famework框架開發(fā)用戶模塊相關(guān)接口的流程,需要注意的點(diǎn),以及源碼。期間重寫了Django用戶模型類,自定義了Django Response消息格式等。此文不過多贅述環(huán)境及各種依賴的安裝過程,如果后續(xù)有需要的話再做進(jìn)一步的補(bǔ)充。
1 項(xiàng)目創(chuàng)建 開發(fā)獲取JWT Token的接口
1.1 創(chuàng)建項(xiàng)目與應(yīng)用
創(chuàng)建項(xiàng)目: django-admin createproject my_project
 創(chuàng)建應(yīng)用: 進(jìn)入到manage.py所在目錄中,python manage.py startapp user
對項(xiàng)目做初步的配置:
 打開項(xiàng)目配置文件settings.py
1.2 開發(fā)獲取JWT Token的接口
因?yàn)槭乔昂蠖朔蛛x的開發(fā),為了不讓接口裸奔,所以必須要和配套的安全機(jī)制一起使用。Django提供了兩種Token,這里使用JWT Token,需要事先安裝djangorestframework-jwt庫。
 最終目標(biāo)是通過訪問地址: http://localhost:8000/login/ 來獲取JWT Token信息。
1.2.1 配置應(yīng)用
打開項(xiàng)目配置文件settings.py,在原有基礎(chǔ)上添加以下配置:
... # 應(yīng)用 INSTALLED_APPS = [...,'rest_framework','rest_framework.authtoken', # 新添加的..., ]# rest_framework配置 REST_FRAMEWORK = {# 配置默認(rèn)過濾器'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),# 配置DRF Token'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_jwt.authentication.JSONWebTokenAuthentication', # JWT認(rèn)證),'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', # 這是接口文檔需要用到的# 配置JWT'JWT_EXPIRATION_DELTA': datetime.timedelta(days=3), # 過期時(shí)間 'JWT_AUTH_HEADER_PREFIX': 'JWT', # 設(shè)置Token頭為 JWT xxxx'JWT_ALLOW_REFRESH': False, # 禁止刷新 }1.2.2 配置接口地址
打開項(xiàng)目配置目錄中的urls.py,添加以下代碼:
from django.contrib import admin from django.urls import path, include from rest_framework.documentation import include_docs_urls from rest_framework_jwt.views import obtain_jwt_tokenurlpatterns = [path('admin/', admin.site.urls),path('docs/', include_docs_urls(title="my_project接口文檔")), # 訪問項(xiàng)目接口文檔的地址path('login/', obtain_jwt_token), # 獲取JWT token ]- 此處需要執(zhí)行遷移:python manage.py migrate
- 然后創(chuàng)建一個(gè)管理員用戶: python manage.py createsuperuser
- 然后訪問login/,輸入用戶名和密碼后,就能獲取到Token了。
但是這么干了之后,調(diào)用login接口返回的只有Token,這顯然是不夠用的,多數(shù)時(shí)候我們還需要用戶的其他信息,比如電話、用戶名等等,這時(shí)候就需要通過重寫用戶模型類+自定義返回認(rèn)證消息來解決了。
1.2.3 重寫用戶模型類 自定義返回認(rèn)證消息
1.2.3.1 重寫用戶模型類
打開user應(yīng)用下的models.py,添加以下代碼:
from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here.# 重寫用戶模型類 需要繼承AbstractUser class MyUser(AbstractUser):SEX = (('男', '男'),('女', '女'),)LEVEL = (('普通會員', '普通會員'),('銀卡會員', '銀卡會員'),('金卡會員', '金卡會員'),('鉑金會員', '鉑金會員'),('鉆石卡會員', '鉆石卡會員'),)STATUS = (('正常', '正常'),('異常', '異常'),)truename = models.CharField(verbose_name="真實(shí)姓名", blank=True, max_length=50)mobile = models.CharField(verbose_name="手機(jī)號碼", max_length=11, default="")sex = models.CharField(max_length=8, verbose_name="性別", choices=SEX, blank=True)birthday = models.DateField(blank=True, null=True)user_img = models.ImageField(verbose_name="頭像", upload_to='user_img', default="")level = models.CharField(max_length=8, verbose_name="會員等級", default="普通會員", choices=LEVEL)status = models.CharField(max_length=8, verbose_name="狀態(tài)", default="正常", choices=STATUS)在項(xiàng)目全局配置文件settings.py中,添加AUTH_USER_MODEL項(xiàng):
... AUTH_USER_MODEL = 'user.MyUser' # 應(yīng)用名.模型類名 ...1.2.3.2 自定義返回認(rèn)證消息
在user應(yīng)用目錄下,新建jwt_utils.py,然后添加以下代碼:
""" 自定義JWT返回的認(rèn)證信息 """def jwt_response_payload_handler(token, user=None, request=None):return {'token': token,'id': user.id,'username': user.username,'email': user.email,'is_active': user.is_active,'mobile': user.mobile,}在項(xiàng)目全局配置文件settings.py中,添加JWT_RESPONSE_PAYLOAD_HANDLER項(xiàng):
# rest_framework配置 REST_FRAMEWORK = {...,'JWT_ALLOW_REFRESH': False, # 禁止刷新'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.jwt_utils.jwt_response_payload_handler', # 自定義認(rèn)證消息 }再次請求 http://localhost:8000/login/,輸入用戶名和密碼之后,看到的就是自定義的認(rèn)證信息:
 
 獲取Token的接口至此結(jié)束,接下來就是開發(fā)用戶注冊的接口了。
2 用戶注冊接口
用戶注冊接口,此處我們假設(shè)接口的入?yún)?用戶名、密碼、手機(jī)號碼和郵箱這四個(gè)字段,還需要對這幾個(gè)字段進(jìn)行校驗(yàn)。
2.1 定義用戶注冊的序列化器
在user應(yīng)用目錄下,新建serializer.py,然后添加以下代碼:
import re from pyexpat import model from rest_framework import serializers from .models import MyUser# 用戶注冊序列化類 class MyUserRegSerializer(serializers.ModelSerializer):class Meta:model = MyUserfields = ('username', 'password', 'email', 'mobile') # 設(shè)置顯示的字段def validate_username(self, username):# 判斷用戶姓名是否已注冊if MyUser.objects.filter(username=username).count():raise serializers.ValidationError("用戶姓名已存在,請查詢")return usernamedef validate_mobile(self, mobile):# 判斷手機(jī)號碼是否已注冊if MyUser.objects.filter(mobile=mobile).count():raise serializers.ValidationError("手機(jī)號碼已存在,請查詢")# 判斷手機(jī)號碼格式是否有誤REGEX_MOBILE = '1[358]\d{9}$|^147\d{8}$|^176\d{8}$'if not re.match(REGEX_MOBILE, mobile):raise serializers.ValidationError("非法手機(jī)號碼")return mobiledef create(self, validated_data):# 重寫create 給密碼加密user = super().create(validated_data)user.set_password(validated_data['password'])user.save()return user2.2 定義視圖
打開user應(yīng)用目錄下的views.py,添加以下代碼:
from django.shortcuts import render# Create your views here. from .models import MyUser from .serializer import MyUserRegSerializer from .custommodelviewset import CustomModelViewSet from rest_framework.viewsets import ModelViewSet# 在此處你可以重寫ModelViewSet,然后繼承自定義ModelViewSet, 讓它能返回標(biāo)準(zhǔn)的自定義消息 class MyUserViewSet(ModelViewSet):queryset = MyUser.objects.all()serializer_class = MyUserRegSerializer2.3 配置路由
配置路由(需要分別在項(xiàng)目全局配置目錄中的urls.py與user應(yīng)用下的urls.py中添加配置項(xiàng)):
- 項(xiàng)目配置目錄中的urls.py(項(xiàng)目的根URLS)中添加:
- 在user應(yīng)用下的urls.py中添加:
2.4 調(diào)用用戶注冊接口
訪問http://localhost:8000/user/users/:
 
 POST可以創(chuàng)建用戶,直接提交到數(shù)據(jù)庫里。那么,接下來就是用戶登接口的開發(fā)了。
3 用戶登錄接口
所謂登錄,其實(shí)不過是一個(gè)鑒權(quán)的過程。鑒權(quán)通過則登錄成功,到下一步操作;否則登陸失敗,進(jìn)行注冊或其他。前面我們已開發(fā)完成的獲取Token的接口,當(dāng)訪問http://localhost:8000/login/的時(shí)候,需要輸入用戶名和密碼,然后后端校驗(yàn),校驗(yàn)成功則返回Token;現(xiàn)在我們想讓用戶通過手機(jī)號和密碼也可以登錄,那么就需要重寫Django自帶的ModelBackend來實(shí)現(xiàn)。
3.1 重寫自定義驗(yàn)證類
打開user應(yīng)用下的views.py,添加以下代碼,增加自定義驗(yàn)證類CustomBackend:
from django.contrib.auth.backends import ModelBackend from django.db.models import Q from django.contrib.auth import authenticate, get_user_model, login, logoutmyuser = get_user_model() class CustomBackend(ModelBackend):"""自定義用戶信息驗(yàn)證類"""def authenticate(self, request, username=None, password=None, **kwargs):try:# 此處還可以加別的驗(yàn)證項(xiàng) 如郵箱等myuser = MyUser.objects.get(Q(username=username) | Q(mobile=username))if myuser.check_password(password):return myuserexcept Exception as e:return None3.2 在全局配置文件settings.py中添加配置項(xiàng)
打開項(xiàng)目全局配置文件settings.py,添加以下代碼:
# 自定義用戶認(rèn)證項(xiàng) AUTHENTICATION_BACKENDS = {'user.views.CustomBackend', }3.3 測試登錄接口
重新訪問http://localhost:8000/login/,輸入電話號碼與密碼:
 
 至此,使用電話和用戶名都可以實(shí)現(xiàn)鑒權(quán),接下來就是用戶信息查詢、修改和刪除的接口了。
4 用戶信息查詢、修改和刪除接口
用戶注冊和用戶修改所需的字段是不一樣的,所以需要重新定義一個(gè)用戶修改的序列化類。再進(jìn)行相關(guān)的權(quán)限配置即可。
4.1 創(chuàng)建用戶信息修改的序列化類
打開user應(yīng)用下的serializers.py文件,增加MyUserUpdateSerializer類:
# 用戶信息修改序列化類 class MyUserUpdateSerializer(serializers.ModelSerializer):username = serializers.CharField(read_only=True,error_messages={'required': "請輸入用戶名",'blank': "用戶名不允許為空",'min_length': "用戶名長度至少3位",})mobile = serializers.CharField(read_only=True)class Meta:model=MyUserfields=('username', 'truename', 'user_img', 'sex', 'email', 'mobile', 'level', 'status')4.2 修改原有的視圖MyUserViewSet
打開user應(yīng)用下的views.py, 修改原有的視圖,添加權(quán)限,并且讓不同的action返回不同的序列化器。增刪改需要用戶身份認(rèn)證,注冊和登錄不需要權(quán)限。
 下面是整個(gè)用戶模塊視圖的所有代碼:
注意: 此處使用了rest_framework的緩存機(jī)制,需要pip install drf-extensions
 然后在全局配置文件settings.py中添加以下配置:
4.3 配置用戶信息修改 更新 查詢的路由
打開user應(yīng)用下的urls.py,添加一下代碼:
user_detail = MyUserViewSet.as_view({'get': 'retrieve','put': 'update','patch': 'partial_update','delete': 'destroy', })urlpatterns = [...,path('users/<pk>/', user_detail), # 新增的路由 ]4.4 接口測試
在postman中測試的結(jié)果(注意此時(shí)需要在headers中增加Authentication:JWT):
 
 PUT和DELETE也可以在POSTman中進(jìn)行測試,大家可以試一試。
總結(jié)
以上是生活随笔為你收集整理的Django rest_framework 后端接口开发 开发与用户相关的一组接口 登录注册与用户信息查询修改的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 大数据分析师面试求职攻略
- 下一篇: cmd下提示“不是内部或外部命令,也不是
