参考:https://blog.csdn.net/qianbin3200896/article/details/86487393
基本流程:
- 用户输入网址请求访问页面(例如http://127.0.0.1:8000/)
- 后端服务器收到请求后开始解析网址
- 根据路由配置文件urls.py中的定义,将网址映射到指定的视图文件views.py中的处理函数home
- 最后由home函数处理请求并返回请求的页面内容index.html。
目录树:
搭建项目
cmd中输入命令:
django-admin startproject ComputeDemo
创建名为ComputeDemo的项目。在项目根目录下(manage.py文件所在目录)输入命令:
python manage.py startapp app
创建名为app的应用。运行项目查看是否正常,输入:
python manage.py runserver
浏览器访问 http://127.0.0.1:8000/
配置并访问页面
用户的访问请求进行配置
将app导入到工程中,打开ComputeDemo-settings.py,找到INSTALLED_APPS字段,app应用添加:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app', #新添加的应用
]
开放访问权限
后期项目部署和访问方便,ALLOWED_HOSTS字段
ALLOWED_HOSTS = ['*',]
# 表示对所有访问用户均不设限制
配置视图处理函数
app-views.py
from django.shortcuts import render
from django.http import HttpRequest
from django.template import RequestContext
# 头部额外引入django的两个访问模块用于http访问
def home(request):
return render(
request,
'index.html',
)
# 添加了访问页面对应的home处理函数,在该函数中并没有执行其它的操作,
# 仅仅是返回刚才制作的index.html页面。
配置访问路由
ComputeDemo-urls.py
from django.conf.urls import url
from django.contrib import admin
import django.contrib.auth.views
import app.views
urlpatterns = [
url(r'^$', app.views.home, name='home'),
]
# 首先导入app文件夹下的views模块,然后通过配置urlpatterns字段实现访问路径和home函数的绑定。
引用Bootstrap进行界面设计
- bootstrap:dist文件夹下三个子文件夹:css、fonts、js。这三个文件夹即为需要导入的前端库。
- jquery:在线计算器需要采用Ajax发送数据。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
# 设定视口viewport和初始访问尺寸initial-scale等使得手机能够友好的进行浏览。
<title>在线计算器</title>
{% load static %}
# django的模板静态资源引用标签;导入标签后,在所有的引用路径前需要添加static标记
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}" />
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
# 理解成一种文件映射,即映射到项目app中的static文件夹
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-xs-1 col-sm-4"> </div>
<div id="computer" class="col-xs-10 col-sm-6">
# 通过bootstrap容器对内容空间进行了分配,bootstrap将整个的网页内容分为12个网格,
# 依据这12个网格进行内容的布局并且实现响应式设计(适配手机浏览)
<input type="text" id="txt_code" name="txt_code" value="" class="form-control input_show" placeholder="公式计算"
disabled />
<input type="text" id="txt_result" name="txt_result" value="" class="form-control input_show" placeholder="结果"
disabled />
<br />
<div>
<button type="button" class="btn btn-default btn_num" onclick="fun_7()">7</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_8()">8</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_9()">9</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_div()">÷</button>
<br />
<button type="button" class="btn btn-default btn_num" onclick="fun_4()">4</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_5()">5</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_6()">6</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_mul()">x</button>
<br />
<button type="button" class="btn btn-default btn_num" onclick="fun_1()">1</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_2()">2</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_3()">3</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_sub()">-</button>
<br />
<button type="button" class="btn btn-default btn_num" onclick="fun_0()">0</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_00()">00</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_dot()">.</button>
<button type="button" class="btn btn-default btn_num" onclick="fun_add()">+</button>
</div>
<div>
<br />
<button type="button" class="btn btn-success btn-lg btn_clear" id="lgbut_clear" onclick="fun_clear()">清空</button>
<button type="button" class="btn btn-primary btn-lg" id="lgbut_compute">计算</button>
</div>
</div>
<div class="col-xs-1 col-sm-2"> </div>
</div>
</div>
<div class="extendContent"> </div>
</body>
</html>
style.css
/*设置整体的背景样式*/
body {
background-image: url("../img/bg.jpg");
background-position: center 0;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
-webkit-background-size: cover;
-o-background-size: cover;
-moz-background-size: cover;
-ms-background-size: cover;
}
/*显示文本框样式进行设置*/
.input_show{
margin-top: 35px;
max-width: 280px;
height: 35px;
}
/*数字按钮样式进行设置*/
.btn_num{
margin: 1px 1px 1px 1px;
width: 60px;
}
/*清空按钮样式进行设置*/
.btn_clear{
margin-left: 40px;
margin-right: 20px;
}
/*用于将背景拉伸,否则在手机上浏览时背景会显示不全*/
.extendContent{
height: 300px;
}
逻辑功能实现
文本框显示与清除
按下数字按钮然后在“公式计算”文本框中显示添加的数字或者运算符号,按下“清空”按钮可以对两个文本框中的数据进行清除。该部分功能主要通过js实现。
在
<body>
标签中添加下述js代码
<script>
var x = document.getElementById("txt_code");
var y = document.getElementById("txt_result");
function fun_7() {
x.value += '7';
}
function fun_8() {
x.value += '8';
}
function fun_9() {
x.value += '9';
}
function fun_div() {
x.value += '/';
}
function fun_4() {
x.value += '4';
}
function fun_5() {
x.value += '5';
}
function fun_6() {
x.value += '6';
}
function fun_mul() {
x.value += '*';
}
function fun_1() {
x.value += '1';
}
function fun_2() {
x.value += '2';
}
function fun_3() {
x.value += '3';
}
function fun_sub() {
x.value += '-';
}
function fun_0() {
x.value += '0';
}
function fun_00() {
x.value += '00';
}
function fun_dot() {
x.value += '.';
}
function fun_add() {
x.value += '+';
}
function fun_clear() {
x.value = '';
y.value = '';
}
</script>
计算结果回传
- 将“公式计算”文本框中的数据以Ajax形式发送给后端服务器,同时能够接受后端服务器发回来的执行结果并且显示在“结果”本文框中。
-
之所以采用Ajax技术,是因为该在线计算器项目是以一种非刷新式的方式提交数据并更新结果,这种方式只需要进行局部更新,使得用户体验更加良好。
在
<body>
标签中添加下述js代码
<script>
function ShowResult(data) {
var y = document.getElementById('txt_result');
y.value = data['result'];
}
</script>
<script>
$('#lgbut_compute').click(function () {
$.ajax({
url: '/compute/', //调用django服务器计算函数 用来设置请求路径
type: 'POST', //请求类型 请求类型为“POST”方式,需要发送的公式通过data字段进行发送
data: {
'code': $('#txt_code').val()
}, //将获取文本框中的公式
dataType: 'json', //期望获得的响应类型为json 整体的数据类型(通讯协议)采用json字符串形式
success: ShowResult //在请求成功之后调用该回调函数输出结果
# 最后success字段用来定义请求成功后需要执行的函数,
# 我们将请求成功后由后台返回计算的结果通过调用ShowResult函数显示出来。
})
})
</script>
后端开发
计算
- 后端除了之前已经写好的home函数,还需要处理前端发送过来的计算公式,
-
由python模块执行计算然后将计算结果以json字符串形式返回给前端。
app-views.py
import subprocess # 引入线程模块用于执行发送过来的计算公式。
from django.views.decorators.http import require_POST
# 获得后台服务器的POST请求权限(否则发过来的请求会被后台服务器阻止)
from django.http import JsonResponse
# 于将计算得到的结果封装成JSON字符串
from django.views.decorators.csrf import csrf_exempt
# 用于规避csrf校验(用于网站防止被跨站攻击)
def run_code(code):
try:
code='print(' + code + ')'
output = subprocess.check_output(['python','-c',code],universal_newlines=True,stderr=subprocess.STDOUT,timeout=30)
except subprocess.CalledProcessError as e:
output = '公式输入有误'
return output
# run_code接收字符串code,然后调用线程模块subprocess的check_output函数进行公式计算。
@csrf_exempt
@require_POST
# 具体的执行函数
def compute(request):
code = request.POST.get('code') # 获取得到需要计算的公式
result = run_code(code) # 函数执行计算并得到结果
return JsonResponse(data={'result':result}) # 将结果进行JSON封装并作为返回值返回
访问路由urls配置
ComputeDemo-urls.py,在urlpatterns字段中添加代码:
urlpatterns = [
url(r'^$', app.views.home, name='home'),
url(r'^compute/$', app.views.compute, name='compute'), #添加针对compute的路由
]
效果
版权声明:本文为m0_47681342原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。