python3 + Django + Mysql + Vue + Element-UI 學習筆記:從0搭建前后端分離的測試工具平台


前言

1、概述

此前一直想把測試工作過程中的一些通用的工具、方法、FAQ,集成為一個通用的測試工具。

也嘗試過用python的Tkinter做的GUI(有興趣的話,見: https://www.cnblogs.com/chenyuebai/p/7150382.html

雖然能用,但缺點也很明顯:不美觀、擴展性差、需要打包下載。

因此,想搭個Web-Browser、前后端分離的測試平台,把測試的一些能力集成上去,順便學習下前后端開發知識。

功能范圍大概包含:

(1)測試數據構造:日常測試、配合聯調,需要多次重復的構造測試數據(接口、落庫表、redis、收發kafka消息...);針對高頻操作沉淀出TOP場景,落到測試平台中。供組內同學,或者訴求方使用

(2)常用查詢:直接查詢庫表,一是查詢環境需要頻繁切換,二是很多字段都是枚舉值,需要二次查詢,效率低;在這里把一些通用的查詢操作固化下來,代碼中將枚舉值轉義,易於理解

(3)常用鏈接地圖:支持區分環境,含公司通用的研發/測試平台地址、小工具地址、FAQ等

(4)定時任務

2、項目結構

(1)后端:python3 + django + mysql

(2)前端:Vue + Element-UI + vue-template + Js

3、功能預覽:

(1)首頁及菜單、系統訪問地圖:

(2)測試數據構造:

 (3)小工具集:

 (4)定時任務

 (5)留言板

 

一、環境准備

1、Python 3.6.1
2、Django 2.2.6    pip安裝即可
3、mysql 5.7.1 + Connector/J 5.1.48
(1)安裝:mysql安裝時需記錄用戶名、密碼
(2)配置時間、字符集:

sql cmd:
set global time_zone = '+8:00';  #修改mysql全局時區為北京時間,即我們所在的東8區
set time_zone = '+8:00';          #修改當前會話時區
flush privileges;            #立即生效

installPath\my.ini:
在[client]節點下添加  default-character-set=utf8
在[mysqld]節點下添加 (注:collation是排序方式)  character-set-server=utf8     collation-server=utf8_general_ci
restart
SHOW VARIABLES LIKE 'char%';

 

(3)本地啟動mysql服務:

CMD: net start mysql_service_ch

(4)數據庫遷移

manage.py makemigrations
manage.py migrate

(5)創建超級用戶

manage.py createsuperuser

(6)設置后台管理界面為中文

setting.py中:
LANGUAGE_CODE = 'zh-hans'  
TIME_ZONE = 'Asia/Shanghai'

 

前端開發環境搭建,參考:

https://www.cnblogs.com/goldlong/p/8027997.html

 

二、創建項目、應用

1、創建項目

django-admin.py startproject MySite運行服務:manage.py runserver      本地訪問:http://127.0.0.1:8000/
ps:若希望外部機器(同一網絡內)訪問本機的Django服務 可:manage.py runserver 0.0.0.0:8080
並將setting.py中,ALLOWED_HOSTS = ['*', ]

2、創建應用

manage.py startapp Post

3、目錄說明

 

 

4、配置數據庫信息

由於選擇的是mysql,需要配置數據庫信息

MySite/__init__.py:

import pymysql pymysql.install_as_MySQLdb()

MySite/setting.py:

DATABASES = {
    'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'USER':'root', "PASSWORD":"passwd123456", "HOST":"127.0.0.1", "PORT":"3306" } }


至此,環境基本搭建完成;

三、功能實現

大概思路

-->  前端瀏覽器訪問/點擊,觸發http請求

-->  后端 MySite\urls.py\urlpatterns中尋找路由信息 --> 調用views.py中的視圖函數-->處理http請求、參數處理、封裝返回 --> 視圖函數調用viewImpl中具體的業務代碼 --> 數據庫處理 --> 組裝結果 --> 返回結果至前端

--> 前端頁面渲染展示

以查詢留言板列表數據的功能為例(部分代碼有刪改):

1、后端接口開發

(1)接口業務邏輯實現:viewImpl.py 

def queryMsgBoardList(self,msgId,msgType,msgAuthor,pageNb,pageSize):
    msgBoardList = []
    totalCount = None
    # 處理分頁
    startIndex = (pageNb-1) * pageSize
    # 組裝查詢條件
    sqlTemplate = '''select **** from test_**** where trigger_type='MSG_BOARD' {} ORDER BY create_time desc limit {},{};'''
    msgIdCondition = ""
    if msgId and msgId != 'undefined':
        msgIdCondition = " and id='{}'".format(msgId)
    msgTypeCondition = ""
    if msgType and msgType != 'undefined':
        msgTypeCondition = " and detail_info like '%{}%'".format(msgType)
    msgAuthorCondition = ""
    if msgAuthor and msgAuthor != 'undefined':
        msgAuthorCondition = " and detail_info like '%{}%'".format(msgAuthor)
    sqlCondition = msgIdCondition + msgTypeCondition + msgAuthorCondition
    querySql = sqlTemplate.format(sqlCondition,startIndex,pageSize)
    try:
        # 查詢留言列表
        sqlRetData = utils.MysqlUtils().executeSql(querySql,"****db_dev")
        No = 1
        for item in sqlRetData:
            detailInfo = json.loads(item[4].replace('\n', '\\r\\n'))
            msgBoard = {"msgId": item[0], "msgType": detailInfo["msgType"],"msgBody": detailInfo["msgBody"],"msgAuthor": detailInfo["msgAuthor"],"createTime": str(item[6]).replace("T", " ")}
            No = No + 1
            msgBoardList.append(msgBoard)
        # 查詢總數量(sql中不帶入分頁條件)
        queryCtSql = "select count(*) from test_**** where trigger_type='MSG_BOARD' {};".format(sqlCondition)
        totalCount = int(utils.MysqlUtils().executeSql(queryCtSql,"coupondb_dev")[0][0])
        Logger.info("queryMsgBoardList success. msgBoardList = {},totalCount={}".format(msgBoardList,totalCount))
    except Exception as e:
        executeResult = str(e) + "\n" + traceback.format_exc()
        Logger.error("queryMsgBoardList 異常:%s" % executeResult)
    finally:
        return msgBoardList,totalCount

 

(2)view層:views.py

def queryMsgBoardList(request):
    # 入參打印
    utils.SysRecord().LoggerInfoBatch(["request = {}".format(request), "request.body = {}".format(request.body),"request.POST = {}".format(request.POST)])
    # 記錄訪問信息
    utils.SysRecord().visitRecord(request)
    # 定義參數,獲取入參
    msgId = request.POST.get("msgId")
    msgType = request.POST.get("msgType")
    msgAuthor = request.POST.get("msgAuthor")
    pageNb = request.POST.get("pageNb")
    pageSize = request.POST.get("pageSize")
    response = {}
    # 校驗入參
    if not WorkTools.StringFactory().batchCheckParams([pageNb,pageSize]):
        Logger.error("Post.views.queryMsgBoardList() 校驗參數失敗,存在入參為空,請檢查")
        return utils.DjangoTools().returnResponse({"code": "1", "message": "queryMsgBoardList() 校驗參數失敗,存在入參為空,請檢查"})
    try:
        # 查詢留言板數據
        pageNb = int(pageNb)
        pageSize = int(pageSize)
        msgBoardList,totalCount = viewImpl.MsgBoard().queryMsgBoardList(msgId,msgType,msgAuthor,pageNb,pageSize)
        # 組裝結果返回
        response["code"] = "0"
        response["message"] = "查詢成功"
        response["msgBoardList"] = msgBoardList
        response["totalCt"] = totalCount
        Logger.info("queryMsgBoardList():查詢成功")
    except Exception as e:
        executeResult = str(e) + "\n" + traceback.format_exc()
        Logger.error("queryMsgBoardList():查詢異常:%s" % executeResult)
        response["code"] = "1"
        response["message"] = executeResult
    return JsonResponse(data=response, json_dumps_params={'ensure_ascii': False})

(3)url層路由配置:urls.py

    path("api/msgBoard/queryMsgBoardList", views.queryMsgBoardList, name="queryMsgBoardList"),

2、前端頁面開發

前端頁面以前用原生JS寫過一些,也是面向百度編碼的水平。且寫出來的頁面不是很美觀,不如找現成的輪子,又快又好看。

聽前端的同事安利了Vue+Element-UI,熟悉了兩天,寫寫簡單頁面夠用了

進入正題:

(1)靜態頁面開發:msgBoard.vue   列表展示部分:

   <div>
      <el-form>
              <el-form-item>
                <el-row>
                  <el-table :data="msgBoardList" row-class-name="mqRowClass" class="msgBoardListClass">
                    <!-- 折疊 -->
                      <el-table-column type="expand">
                        <template slot-scope="props">
                          <el-form label-position="left" inline class="fold-table-expand">
                            <!-- <el-form-item label="序號">
                              <span>{{ props.row.No }}</span>
                            </el-form-item>
                            <el-form-item label="留言類型">
                              <span>{{ props.row.msgType }}</span>
                            </el-form-item> -->
                            <el-form-item label="樓層">
                              <span>{{ props.row.msgBody }}</span>
                            </el-form-item>
                            <!-- <el-form-item label="提交人">
                              <span>{{ props.row.msgAuthor }}</span>
                            </el-form-item>
                            <el-form-item label="留言時間">
                              <span>{{ props.row.createTime }}</span>
                            </el-form-item> -->
                          </el-form>
                        </template>
                      </el-table-column>
                    <!-- 展示列表 -->
                    <el-table-column  label="ID" min-width="10" align="center">
                      <template scope="scope"> {{ scope.row.msgId }} </template>
                    </el-table-column>
                    <el-table-column  label="留言類型" min-width="18" align="center">
                      <template scope="scope"> {{ scope.row.msgType }} </template>
                    </el-table-column>
                    <el-table-column  label="留言內容" min-width="125" align="center" show-overflow-tooltip="true" class="cellClass">
                      <template scope="scope"> {{ scope.row.msgBody }} </template>
                    </el-table-column>
                    <el-table-column  label="提交人" min-width="15" align="center">
                      <template scope="scope"> {{ scope.row.msgAuthor }} </template>
                    </el-table-column>
                    <el-table-column  label="留言時間" min-width="22" align="center">
                      <template scope="scope"> {{ scope.row.createTime }} </template>
                    </el-table-column>
                    <!-- <el-table-column  label="備注" min-width="18" align="center">
                      <template scope="scope"> {{ scope.row.msgComment }} </template>
                    </el-table-column> -->
                    <el-table-column  label="操作" min-width="20" align="center">
                        <template slot-scope="scope">
                          <el-button type="text" @click="replyMsg(scope.row)">回復</el-button>
                          <!-- <el-button type="text" @click="editCrontabTask(scope.row)">批注 - 開發中</el-button> -->
                        </template>
                    </el-table-column>
                  </el-table>
                </el-row>
              </el-form-item>   
        </el-form>
    </div>

(2)調用后端接口:msgBoard.js

import request from '@/utils/request'
import { MessageBox, Message } from 'element-ui'


export function queryMsgBoardList(data) {
    Message({
        message: "請求已發出,請稍等" || 'Info',
        type: 'Info',
        // duration: 5 * 1000
      })
    return request({
      url: '/msgBoard/queryMsgBoardList',
      method: 'post',
      data
    })
  }

請求是基於request.js發出的,模板中已封裝好,修改一下相關的狀態碼校驗即可,不再贅述。

前端開發完成后,cmd敲編譯命令,如果代碼OK,就能夠看到所代碼會被webpack自動打包到dist目錄下了,至此前端開發完成;

3、前后端綁定:settings.py

(1)貼一些關鍵配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            # 配置Django項目的模板搜索路徑
            os.path.join(BASE_DIR, r"vue-admin\dist"),

        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# Add for vuejs  配置一下靜態文件的搜索路徑
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, r"vue-admin\dist\static"),
]

4、啟動服務、訪問

(1)啟動后端服務:manage.py runserver 0.0.0.0:8080 

 

(2)訪問: http://{本地IP}:8080/home 代碼沒有問題的話,就可以進入首頁了;

(3)找到自己所屬的菜單,點擊即可使用上述開發的功能了

 

 

 

 

四、功能迭代

2021.06.10    INIT
2021.06.24    增加生成圖片支持備注文字功能;redis鏈接方式切換為cluster
2021.06.29    生成圖片功能支持中文備注
2021.07.01    修復通過域名訪問靜態文件類型錯誤;生成圖片增加尺寸信息
2021.07.09    域名接入完成;增加mysqldb記錄訪問信息;系統信息頁面增加訪問信息統計功能
2021.07.12    增加支持****調用
2021.07.16    系統信息頁面增加更新信息記錄
2021.07.29    bugfix:按手機號查詢用戶信息功能失敗,適配****
2021.07.30    增加支持按掩碼查詢用戶信息
2021.08.05    增加支持發送mq消息功能;mq搜索框支持模糊搜索;查詢用戶信息增加手機號回顯處理
2021.08.11    查詢用戶信息反查展示真實手機號(掩碼反查****)
2021.08.12    增加支持優惠券一鍵發放、作廢功能
2021.08.26    增加支持廣告位一鍵同步;發送mq頁面;優惠券使用期限調整功能
2021.09.11    增加用戶權益查詢功能
2021.09.15    新增定時任務功能
2021.09.16    生成圖片支持gif格式
2021.09.23    新增留言板,支持留言、回復、分頁展示

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM