结合上图,我们可以清晰地梳理出客户端浏览器与 Django 后端交互的 8 个核心步骤:
views.py 收到请求后进行逻辑处理,如果需要对数据进行读取、存储或修改,就会调用 M (Model 模型) models.py。templates/xxxx.html,将这些动态数据“组装嵌合”进预先设计好的网页结构中,生成完整的页面。省赛工业信创:使用python编程语言,利用django框架,实现工业设备(传感器、智能门锁、传送带等)的自动化程序开发,模拟工业生产的自动化和智能化。
django是一个高级python Web应用框架,可以快速开发安全和可维护的网站。
cmd命令窗口
新建文件夹(如:D:\test),进入test文件夹,选中路径,输入cmd,进入cmd命令窗口。
安装django模块
在cmd命令窗口中执行pip install django命令,安装django模块。
国内源安装命令:pip install django -i 国内源网址
如清华大学源:
pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple/
创建django项目
在cmd窗口中,执行命令django-admin startproject 项目名。
如创建django项目test04:
django-admin startproject test04
项目创建成功后,将项目文件夹test04拖到pycharm快捷方式上,打开pycharm。
运行django项目
在pycharm的“终端”中运行命令python manage.py runserver启动项目,启动成功如下图所示。
创建方法:在pycharm中,右键选中项目文件夹,选择“新建”-“Python软件包”,在弹出的对话框中输入app应用名。
【templates目录:用于存放模板文件,通常是用于动态生成网页的文件。】
创建方法:在pycharm中,右键单击项目文件夹,选择“新建”-“目录”,在弹出的对话框中输入templates。
1、【视图(views.py)文件是Django框架中最重要的组成部分之一,用来负责处理来自客户端的请求,然后返回相应的响应。】
创建方法:在pycharm中,右键单击app应用文件夹,选择“新建”-“Python文件”,在弹出的对话框中输入views。
编辑views.py视图文件,创建视图函数:
from django.shortcuts import render #导入render模块
def to_A1(req): #创建自定义视图函数to_A1(),返回网页模板文件A1.html
return render(req,'A1.html')
2、创建网页模板文件A1.html
创建方法:在pycharm中,右键单击templates文件夹,选择“新建”-“HTML文件”,在弹出的对话框中输入网页模板名A1。
编辑A1.html模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hellow! #网页A1.html返回hellow!
</body>
</html>
【settings.py文件:项目配置文件,包含django项目中app应用注册、templates文件夹路径声明、数据库配置等配置信息。】
app应用注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'a1', #注册app应用a1
]
templates文件夹路径声明
import os #导入os模块
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")], #templates路径声明
'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',
],
},
},
]
【urls.py路由文件,用以定义网页模板文件到视图文件的映射】
import a1.views as a1 #导入视图,并取别名为a1
urlpatterns = [
path('admin/', admin.site.urls),
path('A1',a1.to_A1), #定义网页模板文件A1.html映射视图函数to_A1
]
----------------------------Navicat Premium软件简介---------------------
Navicat premium是一款数据库管理工具。将此工具连接数据库,你可以对数据库进行各种操作。
---------------------------------------------------------------------------
新建连接
执行“文件”->”新建连接”->”MySQL”命令,打开“新建连接(MySQL)”对话框,输入连接名(连接名可以任意英文),测试连接,如连接成功,单击”确定“。
右键单击新建的连接,选择“新建数据库“命令,在打开”新建数据库“对话框中输入数据库名,单击”确定“。
打开新建的数据库,右键单击“表“,执行”新建表“命令。按工业信创赛项任务书建表,表名为data。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #连接mysql
'NAME':'12345', #数据库名
'USER': 'root', #账号
'PASSWORD': '', #密码
'HOST': '127.0.0.1', #主机
'PORT': '3306', #端口号
}
}
在pycharm终端中输入命令:
python manage.py inspectdb > a/models.py
打开models.py,右下角“文件编码”,选择UTF-8,在弹出的对话框中选择“转换”。
from django.shortcuts import render
from a.models import Data
def to_A1(req):
a = Data.objects.all()
for i in a:
print(i.pm2_5)
print('数据库连接成功!')
return render(req,'A1.html')
基本概念
Django数据传递指网页访问时,加载网页script标签中js函数,通过路由映射,调用Views视图函数读取数据(数据可以是数据库中数据,或者设备实时数据),并对该数据进行数据处理,将处理后的数据返回给网页js函数,网页js函数接收到数据后,将数据传递到网页页面上。
Views视图函数
页面函数
函数格式:
def 函数名(req):
return render(req,’网页文件’)
函数功能:渲染页面
数据函数:向前端返回数据
网页js函数:从后端获取数据并展示
设备分为:
这些设备都由后面交换机跟主机进行通信。
操作流程:
搭建环境在python环境中需要装入软件包 在新建的基于django环境下的文件目录中主要包括了在新建的文件名当中的settings这里面要配置的就是要把新建的软件包添加金app当中,第二个就是要配置MySQL的连接,需要配置用户名跟密码端口号跟本机地址。
打开urls(路由文件)文件这里面配置的是你写的网页跟视图的映射,不写这个则无法将数据显示在网页上。
新建一个utils文件 在里面创建一个modbusTcpUtils.py
这一块写的是与设备进行通信的代码(固定代码 要靠记背)
数据库迁移命令:
python manage.py inspectdb > a/models.py
Views:
# 导入json模块,用于Python数据与JSON格式字符串互相转换
import json
# 导入Django时区工具,获取当前标准时间
from django.utils import timezone
# 导入requests库,用于发送HTTP请求(当前代码注释未使用)
import requests
# 导入Django响应类,构造HTTP响应返回前端
from django.http import HttpResponse
# 导入Django渲染函数,用于返回HTML页面
from django.shortcuts import render
# 导入自定义Modbus TCP工具类,连接传感器/控制设备
from utils.modbusTcpUtils import ModbusTcpUtils
# 导入modbus协议指令常量(读寄存器、写线圈等)
import modbus_tk.defines as cst
# 导入数据库模型Data,用于存储采集的环境数据
from task1.models import Data
# 导入随机数模块(当前代码未使用)
import random as r
# Django 视图函数创建区域标识
# Create your views here.
# 页面跳转视图函数:访问/subtask01时打开页面
def to_task2(req):
# 渲染并返回subtask01.html前端页面
return render(req, "subtask01.html")
# 数据获取接口:前端通过/subtask01/getData调用
def get_data(req):
# TODO 获取模拟数据(已注释,备用)
# api_url = "http://" + req.get_host() + "/api"
# TODO 从上述API地址获取JSON数据,存储到变量get中
# data = requests.get(url=api_url).json()
# TODO 获取十合一传感器实时数据
# 获取连接十合一传感器的Modbus TCP连接
conn = ModbusTcpUtils.get_conn1()
# 执行Modbus读取指令:从站1,读保持寄存器,起始地址0,读取11个寄存器数据
data = conn.execute(1, cst.READ_HOLDING_REGISTERS, 0, 11)
# TODO 按照数据要求,对温度、湿度等数据进行单位换算
# 将读取到的元组数据转为列表,方便修改
data = list(data)
# 对所有数据保留2位小数,部分数据×0.01转换真实物理值
data[0]=round(data[0],2) # CO2 保留2位小数
data[1] = round(data[1], 2) # TVOC 保留2位小数
data[2] = round(data[2], 2) # 甲醛 保留2位小数
data[3] = round(data[3], 2) # PM2.5 保留2位小数
data[4] = round(data[4] * 0.01,2) # 湿度 ×0.01换算,保留2位小数
data[5] = round(data[5] * 0.01,2) # 温度 ×0.01换算,保留2位小数
data[6] = round(data[6], 2) # PM10 保留2位小数
data[7] = round(data[7], 2) # PM1.0 保留2位小数
data[8] = round(data[8], 2) # 光照强度 保留2位小数
data[9] = round(data[9] * 0.01,2) # 索引9数据 ×0.01换算,保留2位小数
# 环境调节设备自动控制逻辑
# 获取控制设备(继电器)的Modbus TCP连接
conn = ModbusTcpUtils.get_conn2()
# 判断温度>20度,开启6号设备(排风扇)
if data[5] > 20:
conn.execute(1, cst.WRITE_SINGLE_COIL, 6, 1, 1)
# 否则关闭6号设备
else:
conn.execute(1, cst.WRITE_SINGLE_COIL, 6, 1, 0)
# 判断光照强度<500,开启5号设备(照明灯)
if data[8] < 500:
conn.execute(1, cst.WRITE_SINGLE_COIL, 5, 1, 1)
# 否则关闭5号设备
else:
conn.execute(1, cst.WRITE_SINGLE_COIL, 5, 1, 0)
# 调用函数,把采集的数据保存到数据库
save_data(data)
# TODO 将数据以JSON形式返回至前端界面
# 把数据列表转为JSON字符串,返回给前端AJAX
return HttpResponse(json.dumps(data))
# 数据保存函数:将传感器数据存入数据库
def save_data(apidata):
# TODO 将数据保存至数据库
# 创建Data模型对象,给每个字段赋值
data = Data(
time=timezone.now(), # 数据采集时间
eco2=apidata[0], # 二氧化碳浓度
tvoc=apidata[1], # 挥发性有机物
ch2o=apidata[2], # 甲醛浓度
pm2_5=apidata[3], # PM2.5
humi=apidata[4], # 湿度
temp=apidata[5], # 温度
pm10=apidata[6], # PM10
pm1=apidata[7], # PM1.0
illu=apidata[8], # 光照强度
noise=apidata[10] # 噪音
)
# 执行保存,写入数据库
data.save()
Html:
// AJAX获取后台数据函数
function getData() {
// 向后端接口 /subtask01/getData 发送GET请求
$.get("/subtask01/getData", function (res) {
//TODO AJAX从后台获取处理好的数据,转为数组存入变量data
data = JSON.parse(res)
// 将数据显示到页面对应ID的元素中
$("#data1").text(data[0]) // CO2
//TODO 按示例把所有数据显示在界面上
$("#data2").text(data[1]) // TVOC
$("#data3").text(data[2]) // 甲醛
$("#data4").text(data[3]) // PM2.5
$("#data5").text(data[4]) // 湿度
$("#data6").text(data[5]) // 温度
$("#data7").text(data[6]) // PM10
$("#data8").text(data[7]) // PM1
$("#data9").text(data[8]) // 光照
$("#data10").text(data[10]) // 噪音
})
}
// 页面加载完成后执行
window.onload = function () {
// 页面打开立即获取一次数据
getData()
//TODO 计时器:每3秒执行一次getData,刷新界面数据
window.setInterval(getData, 3000)
}
Urls:
# 访问/subtask01 → 打开页面
path('subtask01', task1.to_task2),
# 访问/subtask01/getData → 获取数据接口
path('subtask01/getData', task1.get_data),