|
目前最流行、最流行的开发方式是将前端和后端分离。分工更加明确和聚焦,前端越来越难。几天不学习,就跟不上节奏。如果一个月不学习,毫不夸张的说,你不适合这个行业。
Django有一个特别强大的第三方包,Django REST framework,在做前端分离开发的时候,强大灵活的构建Web API!
一、安装使用Django REST框架!使用要求:
REST框架需要以下内容:Python(3.5、3.6、3.7、3.8、3.9)姜戈(2.2,3.0,3.1)强烈推荐每一个Python和Django系列的最新补丁版本,只有官方正式支持。
以下软件包是可选的:Pyyaml,uritemplate (5.1+,3 . 0 . 0+)-模式生成支持。Markdown(3 . 0 . 0+)-对可浏览API的Markdown支持。py gments(2 . 4 . 0+)-为降价处理添加语法高亮显示。django-filter(1 . 0 . 1+)-过滤支持。django-guardian(1 . 1 . 1+)-对象级权限支持。安装:
使用pip来安装您想要使用的任何可选软件包。
pip安装djangorestframework
将“rest_framework”添加到INSTALLED_APPS设置中。
INSTALLED_APPS = [...'rest_framework ',]
如果您打算使用可浏览的API,您还需要添加REST框架的登录和注销视图。将以下内容添加到您的根urls.py文件中。
urlpatterns = [...path('api-auth/',include(' rest _ framework . URLs ')]
至此,我们用来构建API的框架已经安装完毕。接下来,我们需要安装一个用于JSON Web令牌认证的第三方JWT包。前端和后端分开开发,JWT验证必不可少。至于它的验证原理,你可以去网上搜一下就知道了!
其次,安装并使用Django REST frameworkSimple JWT,为Django REST框架提供一个JSON Web token认证后端。该项目借鉴了Django REST框架的代码和django-rest-framework-jwt的概念。
安装:
使用pip安装simplejwt
pip安装djangorestframework-simplejwt
然后,在django项目配置settings.py中,将rest _ framework _ simple jwt . authentic ation . jwthoutthentication添加到身份验证类列表中:
REST_frameWORK = {...' DEFAULT _ authentic ation _ CLASSES ':(...' rest _ framework _ simple jwt . authentic ation . jwt authentic ation ',)...}
此外,在您的根urls.py文件(或任何其他url配置)中,包括简单JWT的TokenObtainPairView和TokenRefreshView视图的路由,TokenVerifyView视图用于验证令牌:
from rest _ framework _ simple jwt . views导入(tokenobservpairview,TokenRefreshView,TokenVerifyView)URL patterns =...path('api/token/',TokenObtainPairView.as _ view(),name='token_obtain_pair '),path('api/token/refresh/',TokenRefreshView.as_view(),name='token_refresh '),path('api/token/verify/',TokenVerifyView.as_view(),name='token_verify '),...]
将rest_framework_simplejwt添加到settings.py文件中的INSTALLED_APPS设置中。
INSTALLED_APPS = [...'rest_framework_simplejwt ',...]
并将以下配置添加到项目settings.py文件中
# jwt相关配置来自日期时间导入时间增量simple _ jwt = {' access _ TOKEN _ LIFETIME ':时间增量(小时=1),'REFRESH_TOKEN_LIFETIME ':时间增量(天= 1),' AUTH _ HEADER _ TYPES ':(' Bearer ',' jwt '),}
ACCESS_TOKEN_LIFETIME设置令牌的到期时间;REFRESH_TOKEN_LIFETIME设置刷新令牌的到期时间!AUTH_HEADER_TYPEStoken的请求头类型,更详细的配置请参考官方文档!
三。安装并使用django-simple-captcha包来生成验证码。具体安装使用请参考我的另一篇文章。前后端分开开发和django的表单系统无关,我们只需要序列化!
参考文章:
固定
pip安装django-简单-验证码
将验证码添加到您的INSTALLED_APPS设置中。
INSTALLED_APPS = [...'验证码',...]
将以下视图添加到项目根urls.py!
path('captcha/'),include('captcha.urls '),
最后,别忘了跑步
python manage.py进行迁移python manage.py迁移
至此,我们的第三方包安装完毕。现在,开始我们的逻辑构建和序列化吧!
四、在app的views.py 中创建生成验证码的视图接口# dadmin/views.pyimport base64import jsonfrom django.http import HttpResponsefrom rest_framework.views import APIViewfrom captcha.views import CaptchaStore, captcha_imageclass CaptchaAPIView(APIView):def get(self, request):hashkey = CaptchaStore.generate_key()try:#获取图片idid_ = CaptchaStore.objects.filter(hashkey=hashkey).first().idimgage = captcha_image(request, hashkey)#将图片转换为base64image_base = 'data:image/png;base64,%s' % base64.b64encode(imgage.content).decode('utf-8')json_data = json.dumps({"id": id_, "image_base": image_base })# 批量删除过期验证码CaptchaStore.remove_expired()except:json_data = Nonereturn HttpResponse(json_data, content_type="application/json") 四。创建视图接口# d admin/views . pyimport base 64import JSonfrom django . http importhttpresponsefrom rest _ framework . views导入APIViewfrom captcha.views导入CaptchaStore,captcha _ image类captcha API view(API view):def Get(self,Request):Hashkey = CaptchaStore . generate _ key()[/h首先()。ID[/h IMgage = captcha _ image(request,hash key) #将图片转换为base64image _ base = ' data:image/png;base64,% s“% base64 . b 64 encode(im gage . content)。decode(' utf-8 ')JSON _ data = JSON . dumps({ " id ":id _," image_base": image_base })#批量删除过期验证码captchastore . remove _ expired()除外:JSON _ data = nonereturn httpresponse(JSON _ data)
动词 (verb的缩写)在urls.py中添加验证码接口视图fromviews.captcha导入captcha API viewURL patterns =[path(' captcha/',captchaapiview.as _ view(),name =' captcha _ API') ]
完成以上步骤后,我们得到以下界面。
#登录接口api/token/ POST用户名密码 #刷新令牌接口api/token/refresh/ POST刷新令牌#验证令牌接口API/token/verify/POST token#返回验证码接口api/captcha/
在浏览器中,您可以看到登录界面视图。允许提交用户名和密码字段。如果您需要验证码验证功能,您必须允许提交和验证验证码。这里的做法是重写TokenObtainPairView,先继承它,扩展验证码字段!
开始之前,我们先在项目的同一个目录下创建一个utils的文件夹,然后在里面创建一个get_token.py的文件,构造一个手动返回令牌的方法,供我们随时使用,快速返回令牌!
# utils/get _ token . pyfrom rest _ framework _ simple jwt . tokens导入刷新令牌defget _ tokens _ for _ user(user):#手动返回令牌refresh = refresh token . for _ user(user)return {' refresh ':str(refresh),' access ':str(refresh . access _ token),}
在扩展TokenObtainPairView之前,我们必须先扩展序列化类TokenObtainPairSerializer来构造我们自己的序列化类!
在应用程序中创建一个serializer.py文件,并引入以下代码
from django.utils import timezonefrom rest_framework import serializersfrom rest_framework_simplejwt.serializers import TokenObtainPairSerializerfrom django.contrib.auth import authenticatefrom utils.get_token import get_tokens_for_userfrom captcha.fields import CaptchaStoreclass DmallTokenObtainPairSerializer(TokenObtainPairSerializer):captcha = serializers.CharField(max_length=4, required=True,trim_whitespace=True, min_length=4,error_messages={"max_length": "图片验证码仅允许4位","min_length": "图片验证码仅允许4位","required": "请输入图片验证码"}, help_text="图片验证码")imgcode_id = serializers.CharField(required=True, write_only=True,help_text="图片验证码id")@classmethoddef get_token(cls, user):token = super().get_token(user)token['captcha'] = user.captchatoken['imgcode_id'] = user.imgcode_idreturn tokendef validate_captcha(self, captcha):# 验证码验证try:captcha = captcha.lower()except:raise serializers.ValidationError("验证码错误")img_code = CaptchaStore.objects.filter(id = int(self.initial_data['imgcode_id'])).first()if img_code and timezone.now() gt; img_code.expiration:raise serializers.ValidationError("图片验证码过期")else:if img_code and img_code.response == captcha:passelse:raise serializers.ValidationError("验证码错误")def validate(self, attrs):# 删除验证码del attrs['captcha']del attrs['imgcode_id']authenticate_kwargs = {'username': attrs['username'],'password': attrs['password'],}# 验证当前登录用户self.user = authenticate(**authenticate_kwargs)if self.user is None:raise serializers.ValidationError('账号或密码不正确')# 登录成功返回token信息token = get_tokens_for_user(self.user)return tokenfrom django . utils import time zonefrom rest _ framework import serializerfrom rest _ framework _ simple jwt . serializer import tokengetpairserializerfrom django . contrib . auth import authenticatefrom utils . get _ token import get _ tokens _ for _ userfrom captcha . fields import CaptchaStoreclass dmalltokengetpairserializer(tokengetpairserializer):captcha = serializer。CharField(max_length=4,required=True, trim _ whitespace = true,min _ length = 4,error _ messages = {" max _ length ":"图片验证码只允许4位数","required ":"请输入图片验证码"},help_text= "图片验证码") imgcodeget _ token(user)token[' Captcha ']= user . Captchatoken[' img code _ id ']= user . img code _ idreturn tokendef validate _ Captcha(self,Captcha):#验证码验证try:Captcha = Captcha . lower()except:raise serializer . validation error("验证码错误")first()if img _ code and time zone . now() gt;img _ code . expiration:raieserializer . validation error("图片验证码已过期") else: if img _ code和img _ code . response = = captcha:passelse:H/]raieserializer . validation error("验证码错误")def validate(self,Attr): #删除验证码['captcha'] [/h' password ':attrs[' password '],}#验证当前登录的用户self.user = authenticate(* * authenticate _ kwargs)如果self . user为none:raise serializer . validation error('帐号或密码不正确')#成功登录后返回token信息token = get _ tokens _ for _ user(self。user) returntoken
上面的代码注释已经写的很清楚了,可以自己看代码理解。不难啊!
(此处已添加圈子卡片,请到今日头条客户端查看)在views.py中构造我们自己的登录视图界面!
从rest_framework导入序列化程序从rest_framework_simplejwt.views导入tokenobservpairview从序列化程序导入dmalltokenobservpairserializer类dmalltokenobservpairwise(tokenobservpairwise):# log in成功返回令牌serializer _ class = dmalltokenobservpairserializer
创建我们在urls.py中构建的登录视图接口路由
从。视图导入dmalltokenobsolvepairviewURL patterns =[path(' mytoken/',dmalltokenobsolvepairview . as _ view(),name='mytoken')]
进入界面看到可以提交验证码和验证码id的表单。接下来,前端是活的!我们的后台界面已经完成到这里了!
前端思路是在渲染模板之前先用一个get请求获取到验证码与id,将验证码显示在页面,imgcode id将获取到的默认值付给他,并隐藏该表单,再用post请求发送数据到登录接口就成功了,逻辑非常简单,代码比较多,就不写了,大家按照这个思路自己走一遍!前端的思路是,在渲染模板之前,用get请求获取验证码和id,在页面上显示验证码,imgcode id会把获取的默认值付给他,隐藏表单,然后用post请求把数据发送到登录界面。逻辑很简单,代码很多,就不写了。这个思路我们自己过吧!
参考仓库代码:https://gitee.com/xingfugz/django-mall
如果你也在自学python或者django,请关注我。我会持续更新关于Django和Python的技术干货和小案例! |
|