大家好,又见面了,我是你们的朋友全栈君。
Django的MTV模式
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
-
M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
-
T 代表模板 (Template):负责如何把页面展示给用户(html)。
-
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
注:如下的设计说明都是针对第二版的,也就是pyhton+django+vue实现的。
思想:
先在urls.py中定义好API,然后对应到对应的视图,按照需求定义方法(get,post,delete,put等),然后再去数据库中取数(经过序列化成json字符串)并返回,定义好之后可以使用postman测试下,看看接口有什么问题,然后再前端中安排这些API就好了。
首先看开发完成后的主页面:
上面的*宝和*神是我们的应用名称,总共有这两个应用,然后每个应用有多个服务,如如下的第二行。因此我在设计数据库的时候将这两个表建立表关系,以后再有新的应用只在第一张表中添加:
models.py 文件部分内容:
class Appname(models.Model):
"""应用分类表"""
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32,verbose_name="应用的名称")
title = models.CharField(max_length=32,unique=True,verbose_name="应用的分类")
def __str__(self):
return self.title
class Service(models.Model):
"""服务表"""
appname = models.ForeignKey(to="Appname",verbose_name="应用的分类",on_delete=None)
title = models.CharField(max_length=32,verbose_name="服务的名称")
title_number = models.IntegerField(verbose_name="服务数量", default=1)
def __str__(self):
return self.title
主页面的表的相关东西设计完成之后,下来写获取应用名和获取服务名的api:
总的url控制器,获取相应的应用名和服务名在Automatic中:
Autimatic中相应的内容:
上面的url控制器部分定义完之后,下来时view视图部分:
from rest_framework.views import APIView
from rest_framework.response import Response
from . import models
from .serializers import APPNameSerializer,ServiceSerializer
class AppView(APIView):
def get(self,request):
queryset = models.Appname.objects.all()
ser_obj = APPNameSerializer(queryset, many=True)
return Response(ser_obj.data)
class ServiceclassifyView(APIView):
def get(self,request,pk):
queryset = models.Service.objects.filter(appname_id=pk).all()
print(queryset)
ser_obj = ServiceSerializer(queryset,many=True)
return Response(ser_obj.data)
上面的视图中我们确实从数据库中返回了。但是我们要返回给前端,为了规范,我们使用json字符串进行返回,所以要先对我们从数据库取的数据进行序列化成json格式,你可以使用JsonResponse。在DRF框架中为我们提供了更好的序列化方式:ModelSerializer。
注:此处的截图为部分截图。
model:表示你要序列化的表。
fields是要序列化的字段,当然也可以建立表关系的字段,”__all__”表示所以字段都要进行序列化。对于复杂的字段需要重新构建,使用get_字段名这个方法进行重构。
经过这个序列化处理之后将数据返回。
对于登录接口:
整体流程:前端输入用户名和密码之后,点击登录,然后先使用md5对密码加密,然后给后端发送post请求并携带用户名和密码,在后端取出相应的用户名和密码,然后进行对比,如果成功,会使用uuid生效一个随机数用户token,以token为健,用户名为值保存到redis。
class LoginView(APIView):
def post(self,request):
res = BaseResponse()
username = request.data.get('username','')
pwd = request.data.get('pwd','')
user_obj = Account.objects.filter(username=username,pwd=pwd).first()
if not user_obj:
res.code=1030
res.error='用户名或密码错误'
return Response(res.dict)
#用户登录成功生成token,并写入redis中
conn = redis.Redis(connection_pool=POOL)
try:
token = uuid.uuid4()
conn.set(str(token),user_obj.username)
res.data = token
res.username = user_obj.username
except Exception as e:
res.code = 1031
res.error = '创建令牌失败'
return Response(res.dict)
BaseResponse类是定义一个格式。
class BaseResponse(object):
def __init__(self):
self.code = 1000
self.data = None
self.error = None
@property
def dict(self):
return self.__dict__ #将所有初始化属性组成字典返回
注:对于用户的注册功能并没有做,对于自动化发布平台来讲,根据目前的需求,所以提前在数据库中写入一个用户,注册其实也可以做得,流程是前端的用户和密码信息返回到后端,然后根据ModelSerializer中的序列化之后并使用create方法写入到数据库中。
对于登录认证功能,很多页面都有登录认证,就是访问当前页面或接口之前先进行验证是否登录,此处使用DRF中的登录验证模块:BasrAuthentication。
整体流程:
前端访问后端某些api时,需要进行登录验证时,先在前端判断是否登录,登录之后,将用户名以及从后端返回的token保存到SessionStrorage中,对于需要登录验证的后端API,我们在访问时将token加入到请求头部,当请求到后端时,先从头部信息中拿到相关token,然后再redis中进行判断token是否正常,然后成功返回user,token,对于这一系列后端验证,使用了DRF中的认证模块。
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .redis_pool import POOL
import redis
from Automatic.models import Account
CONN = redis.Redis(connection_pool=POOL)
"""
从请求头部取出token,然后和redis中的token进行对比,成功返回 user,token
"""
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
# 从请求头中获取前端带过来的token
token = request.META.get("HTTP_AUTHENTICATION", "")
if not token:
raise AuthenticationFailed("没有携带token")
# 去redis比对
user_id = CONN.get(str(token))
if user_id == None:
raise AuthenticationFailed("token过期")
user_obj = Account.objects.filter(id=user_id).first()
return user_obj, token
定义好之后,然后再需要进行登录验证的接口的视图前加上这个类就好了。
详细代码联系我,qq:1159291043。
转载于:https://blog.51cto.com/11726212/2379084
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145834.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...