自動化運維平臺(後端python+django)



Django的MTV模式html

Django的MTV模式本質上和MVC是同樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別是值:前端

  1. M 表明模型(Model): 負責業務對象和數據庫的關係映射(ORM)。vue

  2. T 表明模板 (Template):負責如何把頁面展現給用戶(html)。python

  3. V 表明視圖(View): 負責業務邏輯,並在適當時候調用Model和Template。redis

除了以上三層以外,還須要一個URL分發器,它的做用是將一個個URL的頁面請求分發給不一樣的View處理,View再調用相應的Model和Template,MTV的響應模式以下所示:數據庫

image.png

注:以下的設計說明都是針對第二版的,也就是pyhton+django+vue實現的。django

思想:json

        先在urls.py中定義好API,而後對應到對應的視圖,按照需求定義方法(get,post,delete,put等),而後再去數據庫中取數(通過序列化成json字符串)並返回,定義好以後可使用postman測試下,看看接口有什麼問題,而後再前端中安排這些API就行了。後端


首先看開發完成後的主頁面:api

image.png


上面的*寶和*神是咱們的應用名稱,總共有這兩個應用,而後每一個應用有多個服務,如以下的第二行。所以我在設計數據庫的時候將這兩個表創建表關係,之後再有新的應用只在第一張表中添加:

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中:

image.png

Autimatic中相應的內容:

image.png


上面的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。

注:此處的截圖爲部分截圖。

image.png

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

定義好以後,而後再須要進行登陸驗證的接口的視圖前加上這個類就行了。

image.png



詳細代碼聯繫我,qq:1159291043。

相關文章
相關標籤/搜索