我的第一个python web开发框架(15)——公司介绍编辑功能

网友投稿 812 2022-05-29

完成登录以后,就会进入后台管理系统的主界面,因为这个是小项目,所以导航菜单全部固化在HTML中,不能修改。一般后台还会有一个欢迎页或关键数据展示的主页面,小项目也没有多大的必要,所以登录后直接进入公司介绍编辑页面。

首先我们来看一下公司介绍页面内容

看上去功能好像很简单,其实我们要处理的东西还是挺多的。

从页面上看,我们需要有一个记录读取的接口,来获取公司介绍的内容,并展示在页面上。当然现在数据库里面没有记录存在,所以我们还需要向数据库的信息表(infomation)中插入一条公司介绍的记录,这样好直接进行编辑(因为公司介绍不会有很多条记录,一般定了后就不会再改变,所以只需要在数据库的信息表里插入一条就可以了)

另外,从界面上看,我们还需要有一个上传文件的接口,可以上传图片和文件;还需要一个更新公司介绍内容的接口。

还有需要修改几个地方,有上传文件,肯定需要有下载的接口,所以需要增加一个下载的路由(Python与其他语言不一样的地方是,所有访问都必须通过路由,所以上传的或放在目录中的文件需要统一定义一个接口来处理,不然用户访问不了,虽然有点麻烦,但这样处理也安全很多,用户上传任何含有木马或程序的文件,它也无法在服务器端执行);nginx配置文件也需要修改一下,增加下载路径规则,这样就可以直接通过nginx访问下载路径了。

向数据库中添加公司介绍记录

运行pgAdmin连上数据库,然后按第4章的做法,打开sql查询分析器,运行下面代码添加一条数据库记录

INSERT INTO infomation(id, title)  VALUES (1, '公司介绍');

添加公司介绍记录读取接口

@get('/api/about/') def callback():     """     获取指定记录     """     sql = """select * from infomation where id = 1"""     # 读取记录     result = db_helper.read(sql)     if result:         # 直接输出https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.son         return web_helper.return_msg(0, '成功', result[0])     else:         return web_helper.return_msg(-1, "查询失败")

因为公司介绍id添加后不会再改变,所以sql语句直接绑死id为1,另外,执行数据库查询以后,返回的是列表,所以返回记录时要加上序号:result[0]

启动debug(对main.py点击右键=》debug),将用户登录判断那两行注释掉(不然直接访问会返回-404,“您的登录已失效,请重新登录”提示),在浏览器输入:http://127.0.0.1:9090/api/about/就可以看到返回结果(结果的中文字符是unicode编码,需要用站长工具转换一下才可以转为下载效果)

{"msg": "成功", "data": {"content": "", "front_cover_img": "", "id": 1, "title": "公司介绍", "add_time": "2017-10-31 14:17:45"}, "state": 0}

我的第一个python web开发框架(15)——公司介绍编辑功能

添加公司介绍内容修改接口

@put('/api/about/') def callback():     """     修改记录     """     front_cover_img = web_helper.get_form('front_cover_img', '图片')     content = web_helper.get_form('content', '内容', is_check_special_char=False)     # 防sql注入攻击处理     content = string_helper.filter_str(content, "'")     # 防xss攻击处理     content = string_helper.clear_xss(content)     # 更新记录     sql = """update infomation set front_cover_img=%s, content=%s where id=1"""     vars = (front_cover_img, content,)     # 写入数据库     db_helper.write(sql, vars)     # 直接输出https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.son     return web_helper.return_msg(0, '成功')

因为公司介绍只需要一条记录就够了,前面使用手动方式向数据库添加记录,所以代码中我们就不需要写添加的方法

修改记录使用put方式接收:@put('/api/about/')

从界面图片中可以看到,有文章标题、首页图片和文章内容,因为标题不需要进行修改,所以我们修改接口只需要处理剩下两项就可以了。

因为提交的内容含有HTML代码,所以使用web_helper.get_form提取值时,需要使用is_check_special_char参数,设置为不检查特殊符号,不然会接收不了。另外接收到参数值以后,我们需要对它进行防sql注入和防xss处理。

clear_xss()函数是string_helper包新增的清除xss攻击标签用的,它会过滤掉xss的攻击代码。详细代码如下:

def clear_xss(html):     """     清除xss攻击标签     :param html: 要处理的html     :return:     """     tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'li', 'ol', 'strong', 'ul']     tags.extend(         ['div', 'p', 'hr', 'br', 'pre', 'code', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'del', 'dl', 'img', 'sub', 'sup', 'u',          'table', 'thead', 'tr', 'th', 'td', 'tbody', 'dd', 'caption', 'blockquote', 'section'])     attributes = {'*': ['class', 'id'], 'a': ['href', 'title', 'target'], 'img': ['src', 'style', 'width', 'height']}     return bleach.linkify(bleach.clean(html, tags=tags, attributes=attributes))

clear_xss()函数中我们使用了bleach这个库(需要安装:pip install bleach),它是一个基于白名单、通过转义或去除标签和属性的方式,来对HTML文本净化的python库。

我们在string_helper_test.py这个测试单元中添加一个测试用例,来测试一下这个函数的使用效果

def test_clear_xss(self):         print('-----test_clear_xss------')         print(string_helper.clear_xss('abc'))         print(string_helper.clear_xss(''))         print(string_helper.clear_xss('abc

'))         print(string_helper.clear_xss(""""""))         print(string_helper.clear_xss('abc

'))         print(string_helper.clear_xss('abc'))         print(string_helper.clear_xss('abc'))         print(string_helper.clear_xss('abc'))         print(string_helper.clear_xss('文字'))         print(string_helper.clear_xss('文字
'))         print(string_helper.clear_xss(''))         print(string_helper.clear_xss('alert(/XSS/)"/>'))         print(string_helper.clear_xss(''))         print(string_helper.clear_xss('alert%28document.cookie%29%3B
'))         print(string_helper.clear_xss('eval(unescape(x.innerHTML));'))

执行后输出结果:

------ini------ -----test_clear_xss------ <script src="https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_61644.">

abc

<input onclick="https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.avascript:alert('handsome boy')" type="text" value="琅琊榜">

abc

abc abc abc <marquee onstart="alert(/XSS/)">文字</marquee>
文字
  • <input <script="" id="1" type="text" value="">alert(/XSS/)"/> <base href="http://www.labsecurity.org"> alert%28document.cookie%29%3B
    <limited_xss_point>eval(unescape(x.innerHTML));</limited_xss_point> ------clear------

    可以看到,对于富文本编辑器提交的代码,bleach基本满足了我们的防范xss攻击的处理需求

    添加上传接口(PS:我们使用的文本编辑器是百度的ueditor,因为它没有python的上传处理代码,所以我们需要动手编辑上传接口,以及html上也要进行对应的修改)

    #!/usr/bin/evn python # coding=utf-8 import os from bottle import post, request from common import datetime_helper, random_helper, log_helper @post('/api/files/') def callback():     """     修改记录     """     # 初始化输出值     result = {         "state": "FAIL",         "url": "",         "title": "上传失败",         "original": ""     }     # 获取上传文件     try:         # upfile为前端HTML上传控件名称         upload = request.files.get('upfile')         # 如果没有读取到上传文件或上传文件的方式不正确,则返回上传失败状态         if not upload:             return result         # 取出文件的名字和后缀         name, ext = os.path.splitext(upload.filename)         # 给上传的文件重命名,默认上传的是图片         if ext and ext != '':             file_name = datetime_helper.to_number() + random_helper.get_string(5) + ext         else:             file_name = datetime_helper.to_number() + random_helper.get_string(5) + '.https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.pg'         upload.filename = file_name         # 设置文件存储的相对路径         filepath = '/upload/' + datetime_helper.to_number('%Y%m%d') + '/'         # 组合成服务器端存储绝对路径         upload_path = os.getcwd() + filepath         # 如果目录不存在,则创建目录         if not os.path.exists(upload_path):             os.mkdir(upload_path)         # 保存文件         upload.save(upload_path + upload.filename, overwrite=True)         # 设置输出参数(返回相对路径给客户端)         result['title'] = result['original'] = upload.filename         result['url'] = filepath + upload.filename         result['state'] = 'SUCCESS'     except Exception as e:         log_helper.error('上传失败:' + str(e.args))     # 直接输出https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.son     return result

    PS:这里只做了上传文件处理,没有上传成功以后存储到数据库中统一管理,如果前端反复上传,会造成服务器存储很多多余文件的问题,大家可以自己发挥想象与动手能力,看看怎么解决这个问题。对于这个问题会在第二部分统一处理。

    添加上传文件存储文件夹:直接在项目的要目录下创建upload文件夹

    修改main.py文件配置,并创建文件下载路由

    导入的bottle库添加response, static_file这两个包,response用于设置输出文件类型为二进制数据传输格式,这样设置后,上传的各种类型文件都可以下载;static_file是使用安全的方式读取文件并输出到客户端

    from bottle import default_app, get, run, request, hook, route, response, static_file

    在第26行插入下面代码,初始化上传文件存储路径

    # 定义upload为上传文件存储路径 upload_path = os.path.https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.oin(program_path, 'upload')

    添加下载文件访问路由,设置后只要放在upload目录下的文件都可以直接通过浏览器下载

    @get('/upload/') def upload_static(filepath):     """设置静态内容路由"""     response.add_header('Content-Type', 'application/octet-stream')     return static_file(filepath, root=upload_path)

    做完以上设置,上传与更新就没有问题了,上传的图片直接使用http://127.0.0.1:9090/upload/xxx.https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.pg方式就可以访问了,如果想要使用81端口,也就是通过nginx访问,那就需要再配置一下

    打开nginx配置文件 :E:\Service\nginx-1.11.5\conf\nginx.conf

    将location ~* ^/(index|api)/ 修改为 location ~* ^/(index|api|upload)/

    然后在windows任务管理器(键盘同时按Ctrl+Alt+Del键,点击启动任务管理器),找到nginx_service.exe,右键=》结束进程树

    重新打开服务(控制面板=》所有控制面板项=》管理工具=》服务),启动nginx_service服务

    前端页面相关修改

    向/lib/ueditor/1.4.3/目录中添加python文件夹,将添加config.https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.son这个配置项

    修改/lib/ueditor/1.4.3/ueditor.config.https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.s 配置项中 服务器统一请求接口路径 为 /api/files/

    本文对应的源码包里有ueditor编辑器最新代码(刚刚去百度下载的),去掉了多余的文件,大家可直接删除lib目录里的ueditor这个文件夹,使用源码包里的替换上去就可以了

    前端页面的https://www.huoban.com/news/zb_users/upload/2022/05/20220529112717_85666.avascript脚本添加了ueditor编辑器初始化、文件上传和表单提交等功能,可直接替换about_edit.html文件,具体大家自己研究一下。

    最终效果:

    另外,联系我们的功能与公司介绍差不多,在这里留一下作业给大家自己尝试做一个联系我们编辑页面出来,下一篇会给联系我们编辑页面源码给大家

    本文对应的源码下载

    python

    版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

    上一篇:Lucene 同义词
    下一篇:阅读的正确姿势 ——《如何阅读一本书》
    相关文章