实战项目一:bootstrap+Ajax+django实现web计算器

web计算器

      • 前言
      • 0、知识点
        • 0.1 创建django项目后,各文件的含义
        • 0.2 在项目中创建应用,应用中各个文件的作用
        • 0.3 django项目和应用的关系
      • 1、创建项目
      • 2、配置并访问页面
        • 2.1 制作用于访问的页面
        • 2.2 对用户访问请求进行路由配置
        • 2.3 配置视图处理函数
        • 2.4 配置访问路由
      • 3、导入bootstrap前段框架
        • 3.1 bootstarp配置
        • 3.2 编写html文件
      • 4、前端页面设计和功能开发
        • 4.1 页面制作
        • 4.2 对界面进行美化
        • 4.3 前端页面的逻辑功能实现
      • 5、开发后端计算模块

前言

  本文的内容来自《python web开发从入门到实战》这本书,本人进行了实际操作了解整个pyton web开发的过程。
   前端采用bootstrap进行制作,提供输入框和按钮让用户进行信息输入,然后将计算式通过Ajax方式传输给后台进行计算。后台采用Django进行开发,获取到前端发送的数据后利用python的子进程模块subprocess来计算式子,并将计算结果返回给前段进行显示。

0、知识点

0.1 创建django项目后,各文件的含义

  使用django-admin startproject compute创建项目后,项目工作目录下有一个manage.py文件以及一个与项目名字形同的compute子文件夹。manage.py文件作为项目的主文件,用来执行与项目相关的一些重要命令,例如,项目的启动、数据库的同步、后台管理员的创建、静态文件的迁移等。在compute子文件夹下有几个python文件,下面对这些文件做基本介绍:

   目录: D:\python web学习\compute\compute\compute


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/2/20     10:57                __pycache__
-a----         2021/2/20     10:48            407 asgi.py
-a----         2021/2/20     10:48           3185 settings.py
-a----         2021/2/20     10:48            770 urls.py
-a----         2021/2/20     10:48            407 wsgi.py
-a----         2021/2/20     10:48              0 __init__.py

init.py:表示文件,可以是一个空文件。主要用来表明当前文件所在的文件夹是一个python包,在这里的作用是声明compute子文件夹为一个独立的模块。
  setting.py:整个项目的全局配置文件。各种应用、资源路径、模板等配置均在此文件中设置。
  urls.py:网络访问的页面映射文件。创建的web项目下所有的页面路由都需要在该文件中配置,否则在访问的时候会找不到对应的页面。
  wsgi.py:全称是web server gateway interface,即网络服务器的网管接口。在这里是指python应用与web服务器交互的接口,一般不需要做任何修改。
  上面四个文件中需要重点股占虎setting.py和urls.py文件,这两个文件是项目中经常需要修改和编辑的文件。

0.2 在项目中创建应用,应用中各个文件的作用

  0.1所创建的项目仅仅是一个web项目的外壳,为了能够满足特定的功能需求需要创建特定的功能对应的应用。

# 在项目中创建应用
python manage.py startapp app

# 可以看到项目中多出来一个app的文件夹
    目录: D:\python web学习\compute\compute


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/2/20     10:56                app
d-----         2021/2/20     10:56                compute
-a----         2021/2/20     10:57              0 db.sqlite3
-a----         2021/2/20     10:48            685 manage.py

# 展开文件夹
PS D:\python web学习\compute\compute> cd app
PS D:\python web学习\compute\compute\app> dir


    目录: D:\python web学习\compute\compute\app


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/2/20     10:56                migrations
-a----         2021/2/20     10:56             66 admin.py
-a----         2021/2/20     10:56             86 apps.py
-a----         2021/2/20     10:56             60 models.py
-a----         2021/2/20     10:56             63 tests.py
-a----         2021/2/20     10:56             66 views.py
-a----         2021/2/20     10:56              0 __init__.py

  migrations:数据库迁移文件夹,在执行数据库迁移的时候会产生一些中间结果,这些结果就存放在该文件夹中。
init.py:表示文件,可以是个空文件,用来表明当前创建的app文件夹是一个python模块。
  admin.py:管理员配置文件,主要是用来注册一些数据库中的模型到后台管理。django给每个项目提供了一个强大的后台管理系统,为了能够在后台管理系统中管理数据库中的数据,需要通过配置admin.py文件来确认那些数据信息可以被后台管理系统管理。
  apps.py:应用的配置文件,一般情况下不需要修改。
  models.py:数据库文件,用来管理数据库中的模型数据。
  tests.py:测试文件,在这里可以对应用做一些测试。
  .view.py:视图文件,对于每个访问的实际处理操作都在这个文件中编写,在这个文件中定义每个访问/路由的处理函数,每个访问与那个函数绑定则由urls.py文件配置。
  上述几个文件需要关注的是:views.py、models.py、admin.py。另外还有几个重要文件需要手动进行创建。其实这些文件的内容结构本身并没有严格的限定,可以吧所有的内容都合并到一个文件中,之所以定义这几个文件是为了方便区分功能。

0.3 django项目和应用的关系
  1. 一个django项目中包含一组配置(指与项目同名的子文件夹),和若干个django应用
  2. 一个django应用就是一个可重用的python包,实现一定的功能
  3. 一个django项目可以包含多个django应用
  4. 一个django应用也可以被包含到多个django项目中,因为django应用是可重用的python包。

1、创建项目

前提准备工作:已经安装了pyghon、vscode、django

# 在cmd或者vscode的终端中创建项目
django-admin startproject compute

# 切换到项目工作目录,manage.py文件目录下,创建一个名为app的应用
PS D:\python web学习\compute> cd .\compute\
PS D:\python web学习\compute\compute> dir


    目录: D:\python web学习\compute\compute

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/2/20     10:48                compute
-a----         2021/2/20     10:48            685 manage.py
PS D:\python web学习\compute\compute> python manage.py startapp app
PS D:\python web学习\compute\compute> dir


    目录: D:\python web学习\compute\compute


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/2/20     10:56                app
d-----         2021/2/20     10:56                compute
-a----         2021/2/20     10:48            685 manage.py
System check identified no issues (0 silenced).

# 启动项目
PS D:\python web学习\compute\compute> python .\manage.py runserver
# ctrl+c退出项目

项目启动后,通过浏览器访问http://127.0.0.1:8000,查看是否正常
实战项目一:bootstrap+Ajax+django实现web计算器_第1张图片

2、配置并访问页面

首先梳理一下页面访问的基本流程,具体包括下面几个步骤:

  1. 用户输入网址请求访问页面,例如输入http://127.0.0.1:8000/
  2. 后端服务器收到请求后开始解析网址,根据路由配置文件urls.py中定义的路由,将网址映射到指定的视图处理函数home()
  3. home()函数处理请求并返回请求的页面内容index.html
2.1 制作用于访问的页面

    在app文件夹下创建一个templates子文件夹,注意该文件夹的名字必须为templates,因为django框架会自动搜索每个应用下的templates文件夹,如果命名拼写错误,后面运行项目时会出现找不到模板文件的错误提示。在templates文件夹下创建一个index.html文件编辑html文件。

PS D:\python web学习\compute\compute> cd .\app\
PS D:\python web学习\compute\compute\app> md templates
PS D:\python web学习\compute\compute\app> cd .\templates\

# 创建index.html文件,并写入html代码
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>在线计算器</title>>
    </head>>

    <body>
        <h1>一款在线计算器</h1>
    </body>
</html>
2.2 对用户访问请求进行路由配置

打开项目配置文件compute下的setting.py文件,知道到INSTALLED_APPS字段,将创建的app应用添加进来。
实战项目一:bootstrap+Ajax+django实现web计算器_第2张图片
为了后期项目部署和访问方便,需要开放访问权限,找到ALLOWED_HOSTS字段。进行下面编辑
实战项目一:bootstrap+Ajax+django实现web计算器_第3张图片

2.3 配置视图处理函数

配置视图处理函数,编辑app文件夹下的view.py文件
实战项目一:bootstrap+Ajax+django实现web计算器_第4张图片
从django包中的shortcuts模块中引入render()函数,用于页面的渲染,然后添加了访问首页对应的home()处理函数,在该函数中并没有执行其他的操作,仅仅是通过render()函数返回index.html页面。

2.4 配置访问路由

编辑配置文件夹compute中的urls.py文件
实战项目一:bootstrap+Ajax+django实现web计算器_第5张图片
首先导入app应用下的views模块,然后通过配置urlpatterns字段将根访问路径(默认http://127.0.0.1:8000)和home()函数进行绑定。

在cmd中启动项目

PS D:\python_web_study\compute\compute> python manage.py runserver 

结果展示:
实战项目一:bootstrap+Ajax+django实现web计算器_第6张图片

3、导入bootstrap前段框架

3.1 bootstarp配置

下载bootstrap
链接: https://github.com/twbs/bootstrap/archive/v3.3.7.zip

将下载好的bootstrap源代码解压,找到其中的dist文件夹,该文件夹下有三个文件件:css、fonts和js。这三个子文件夹为需要导入的前段配置文件。
实战项目一:bootstrap+Ajax+django实现web计算器_第7张图片
接下来,在compute项目的app文件夹下面创建一个名为static的子文件夹,然后将bootstrap中的css、fonts、js三个文件夹复制到static文件夹下面。并且在static文件夹下新建一个名为img的子文件夹用于存放静态图片。

下载bootstrap3.3.7对应的jquery
链接: http://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
按ctrl+s组合键进行保存,保存为jquery.min.js文件。将文件保存到app/static/js中。

3.2 编写html文件

{% load staticfiles %}

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        
        <meta name="viewport" content="width=device-width,initial-scal=1">
        <title>在线计算器title>>

        
        <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" />
        
        <link rel="stylesheet" href="{% static 'css/style.css' %}" />
        <script src="{% static 'js/jquery.min.js' %}">script>
        <script src="{% static 'js/bootstrap.min.js' %}">script>

    head>>

    <body>
        
        <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>
    body>
html>

实战项目一:bootstrap+Ajax+django实现web计算器_第8张图片

4、前端页面设计和功能开发

4.1 页面制作

目标设计页面:
实战项目一:bootstrap+Ajax+django实现web计算器_第9张图片
页面设计分解:
两个文本框组件–一个用于显示计算器公式、一个用于显示计算结果
16个公式编辑按钮,包含数字、小数点和加减乘除等
两个逻辑按钮,一个用于清空文本框内容、一个用于执行公式计算

编辑index.html的body部分


{% load staticfiles %}

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        
        <meta name="viewport" content="width=device-width,initial-scal=1">
        <title>在线计算器title>

        
        <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" />
        
        <link rel="stylesheet" href="{% static 'css/style.css' %}" />
        <script src="{% static 'js/jquery.min.js' %}">script>
        <script src="{% static 'js/bootstrap.min.js' %}">script>
    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 c0l-sm-6">
                    
                    <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()">7button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_8()">8button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_9()">9button>
                    <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()">4button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_5()">5button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_6()">6button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_mul()">×button>
                    <br/>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_1()">1button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_2()">2button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_3()">3button>
                    <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()">0button>
                    <button type="button" class="btn btn-default btn_num" onclick="fun_00()">00button>
                    <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>

name设置属性分组
value是按钮的名字

4.2 对界面进行美化

编辑css文件夹中的style.css文件

/* 设置整体的背景样式 */
body {
    background-image: url("../img/ka.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;
}

重启项目之后的效果:
实战项目一:bootstrap+Ajax+django实现web计算器_第10张图片

4.3 前端页面的逻辑功能实现

   单机数字按钮在“公式计算”文本框中显示添加的数字或者运算符号;单机“清空”按钮,可以对两个文本框中的数据进行清楚。该部分功能主要通过javascript代码实现。

添加到body末尾

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

document.getElementById(“txt_code”) 获取id为txt_code中的内容

单机“计算”按钮,将“公式计算”文本框中的数据通过Ajax发送给后端服务器,同时能够接受后端服务器发回来的执行结果并且显示在“结果”文本框中。之所以采用Ajax,是因为该项目适宜采用局部刷新的方式提交数据并更新结果,这样可以有较好的用户体验。

<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',     // 请求类型
                data: {
                    'code': $('#txt_code').val() // 获取文本框中的公式
                },           
                dataType: 'json',   // 期望获得的响应类型为json
                success: ShowResult // 在请求成功之后调用该回调函数输出结果
            })
        })
    </script>

其中url用来设置请求路径,即将请求提交到“当前根网址/compute/”进行计算

5、开发后端计算模块

在app文件夹中的view.py文件中,添加下列代码

from django.shortcuts import render
import subprocess
from django.views.decorators.http import require_POST
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

# Create your views here.


def home(request):
    return render(request, 'index.html')


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


@csrf_exempt
@require_POST
def compute(request):
    code = request.POST.get('code')
    result = run_code(code)
    return JsonResponse(data={'result': result})

   头部首先通过import subprocess引入子进程模块用于执行发送过来的计算公式;然后引入require_POST装饰器来获得后台服务器的post请求权限(否则发过来的请求会被后台服务器阻止);接下来引入JsonResponse模块用于将计算得到的结果封装成JSON字符串;最后引入csrf_exempt装饰器用于规避csrf校验(防止网站被跨站攻击)。
   在公式计算run_code函数中,主要通过调用子进程模块subprocess的check_output函数进行公式计算。

   最后,需要对访问路由urls进行配置,变价compute中的urls.py文件,在urlpatterns字段中添加代码,

from django.contrib import admin
from django.urls import path
from app.views import home, compute   # 导入首页对应的处理函数


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home, name='home'),    # 首頁路由
    path('compute/', compute, name='compute'),      # 添加針對公式計算compute的路由
]

结果展示:
实战项目一:bootstrap+Ajax+django实现web计算器_第11张图片

你可能感兴趣的:(python,web开发从入门到实践)