Flask,get到的一些知识点(个人向)
更新提醒
从2018年3月3日开始会对更新时间和内容进行介绍
1. 2018年3月3日 11点24分 ——-> 一、3小点( selectfield数据无法及时更新问题)进行了修改 点击跳转
2. 2018年3月3日 16点19分 ——-> 二、3小点(级联删除)进行了修改,删除了原来所写的内容,并对其进行完善 点击跳转
3. 2018年3月3日 23点12分 ——-> 八、(summernote插件)新增了对summernote读取内容的介绍 点击跳转
4. 2018年3月4日 10点19分 ——-> 八、(summernote插件)新增了用红色标注的特别提示 点击跳转
5. 2018年3月5日 17点49分 ——-> 二、(数据库的高级查询)新增了数据库的高级查询 点击跳转
6. 2018年3月6日 13点59分 ——-> 六、(Jinja2)新增了数据库中的dateime格式在页面中显示date格式 点击跳转
7. 2018年3月6日 14点09分 ——-> 二、(数据列表翻转reverse())新增了数据列表翻转reverse() 点击跳转
8. 2018年3月6日 17点42分 ——-> 七、(database插件)对内容进行了完善 点击跳转
9. 2018年3月7日 10点15分 ——-> 二、(数据库的高级查询)新增了new 点击跳转
10. 2018年3月7日 16点51分 ——-> 九、(pycharm相关)新增了pycharm相关 点击跳转
11. 2018年3月8日 16点56分 ——-> 二、(关于对象关系的理解)新增了蓝字部分 点击跳转
12. 2018年3月8日 16点58分 ——-> 六、(模板空格去除)新增了模板空格去除 点击跳转
13. 2018年3月8日 17点05分 ——-> 六、(datetime的计算)新增了datetime的计算(6.2.2) 点击跳转
14. 2018年3月8日 17点05分 ——-> 二、(datetime相关)新增了datetime相关(2.6) 点击跳转
15.2018年3月9日 23点14分 ——-> 十、(sweet-alert插件)sweet-alert插件(10) 点击跳转
16.2018年3月11日 20点44分 ——-> 十一、(flask-mail邮箱配置及使用)新增flask-mail邮箱配置及使用 点击跳转
17.2018年3月12日 12点21分 ——-> 七、(database插件)新增7.2 控制Datatables元素的位置(dom) 点击跳转
18. 2018年3月27日 21点47分 ——-> 十二、(morris.js插件)新增十二、 morris.js插件 点击跳转
19. 2018年3月27日 23点36分 ——-> 十三、(Highcharts插件)新增十三、Highcharts插件 点击跳转
20. 2018年3月28日 13点44分 ——-> 十四、(Arrow-一个最好用的日期时间Python处理库)新增十四、Arrow-一个最好用的日期时间Python处理库 点击跳转
特别标注:本篇文章所讲述的代码均来自个人项目 Online-Registration 对此项目有什么相关建议欢迎在评论下提出。
html生成时,属性指向
- forms.py
name = StringField(
label="添加新闻类别",
validators=[
DataRequired("请输入新闻类别")
],
description="新闻类别",
render_kw={
"class": "form-control",
"id": "add_info",
"placeholder": "请输入新闻类别",
} # 附加选项
)
- xxx.html
<div class="form-group">
{{ form.name.label(for='add_info', class='form-margin') }}
{{ form.name }}
</div>
get到,label那里可以自己加属性表单属性
http://wtforms.simplecodes.com/docs/0.6.1/fields.html
用此文档解决了selectfield动态选择数据selectfield数据无法及时更新问题
form.py中一开始是先从数据库中查询数据出来,然后在selectfield的choices中塞进去查询出来的数据。此方法不能及时更新数据,故不建议使用。代码如下
在views.py的相应功能函数中添加如下代码:# 每次刷新列表 form.category.choices = [(v.id, v.name) for v in NewsCategory.query.all()]注:以上代码均在views.py中
参考网站:https://segmentfault.com/q/1010000011641873
二、数据库相关
数据库(整个)删除后报错问题
https://segmentfault.com/q/1010000005649683
https://stackoverflow.com/questions/7191758/how-to-set-up-a-table-with-a-recursive-foreign-key-and-a-relationship-declarativ关于对象关系的理解
get到relationship中的backref=”外键名(tlevel)”,在引用表(Tinfo)中通过对象(tinfo).外键名(tlevel).属性(level)级联删除
解决了一对多级联删除中,删掉一(主)表但是多(参考)表中外键为空,数据行仍在多(参考)表的问题,代码如下:
newscategory:# 新闻类别
class NewsCategory(db.Model):
其余的代码均舍弃,挑重要的写出来
newstags = db.relationship("NewsTag", backref='newscategory', cascade='all, delete-orphan', lazy='dynamic',passive_deletes=True)newtag:# 新闻标签 class NewsTag(db.Model): 其余的代码均舍弃,挑重要的写出来 newscategory_id = db.Column(db.Integer, db.ForeignKey('newscategory.id', ondelete='CASCADE')) addtime = db.Column(db.DateTime, index=True, default=datetime.now) newsinfos = db.relationship('NewsInfo', backref='newstag', cascade='all, delete-orphan', lazy='dynamic', passive_deletes=True)以上代码均在models.py中
数据库的高级查询
以Online-Registration的admin/view.py中的代码为例:
oplog_list = Oplog.query.order_by( Oplog.addtime.asc() ) oplog_book_list = oplog_list.filter(Oplog.opdetail.like('%参考书%')) oplog_book_list = oplog_book_list[oplog_book_list.count() - 3:]New:ilike以及其它的用法,参考网站:https://www.jianshu.com/p/5a27a826866e
参考网站:http://www.cnblogs.com/huangxm/p/6295102.html
解析:Oplog为数据库中的表,opdetail为其表中的一列,like为模糊匹配。对oplog_list里的数据进行模糊匹配,找出带有参考书样式的日志集合,其次找出后三条相关数据。
参考网站:https://www.bbsmax.com/A/A2dmNGBnze/数据列表翻转reverse()
oplog_book_list = oplog_list.filter(Oplog.opdetail.like('%参考书%')) oplog_book_list = oplog_book_list[oplog_book_list.count() - 3:] oplog_book_list.reverse() return render_template("admin/index.html", oplog_book_list=oplog_book_list)结果如下
参考网站:http://blog.****.net/guoziqing506/article/details/51966025datetime相关
参考网站:http://www.wklken.me/posts/2015/03/03/python-base-datetime.html
三、正则表达式
四、上传相关
- 上传时,form表单一定要加上:
enctype="multipart/form-data"- 多文件上传(插件为:bootstrap-fileinput)
官网:https://github.com/kartik-v/bootstrap-fileinput
其他:http://www.os373.cn/article/81
其他:http://blog.****.net/qq_28550739/article/details/53436080
其他:http://blog.****.net/u012526194/article/details/69937741
1 给input添加multiple属性(或者在forms.py中的render_kw添加此属性){{ form.img(multiple="multiple")}}2 在获取文件时从request对象获取,并迭代保存
from flask import request ... for filename in request.files.getlist('photo'): photos.save(filename) ...3 views.py中
for imgs in request.files.getlist('img'):
print(imgs)
注:imgs有filename的属性
img为forms.py中的属性,完整步骤见下图
详见知乎专栏:https://zhuanlan.zhihu.com/p/24429519
五、个人中心数据传递(理解get方式时的数据传递)
views.py
@registration.route("/userinfo/", methods=["GET", "POST"]) def userinfo(): form = UserInfoForm() user = User.query.filter_by(id=session['user_id']).first_or_404() if request.method == "GET": form.gender.data = user.gender form.id_card.data = user.id_card form.phone.data = user.phone form.area.data = user.area if form.validate_on_submit(): pass return render_template("registration/userinfo.html", form=form, user=user)userinfo.html(摘取2部分)
<div class="col-md-10"> {{ form.email(value=user.email) }} </div>
<div class="col-md-10"> {{ form.gender }} </div>
六、Jinja2
1 for的一个小用法,loop.index。能自动生成序列(1开始)排序
{% for value in page_data %} <tr> <td>{{ loop.index }}</td> <td>{{ value.user.name }}</td> <td>{{ value.user.email }}</td> <td>{{ value.ip }}</td> <td>{{ value.addtime }}</td> </tr> {% endfor %}2 数据库中的dateime格式在页面中显示date格式
datetime有一个这样的方法:
date_time.strftime('%Y-%m-%d')
故在jinja2前台显示的时候可以这样写:{{ newscategory.addtime.strftime('%Y-%m-%d') | safe }}
注: newscategory.addtime为datetime格式
结果如下
参考网站:https://www.jianshu.com/p/ba8492753ef6
2.2 由于Jinja2模板不支持datetime类型的值,故在views.py中将值列好传递至template。(机智的网友们)
部分代码如下:import datetime
now = datetime.datetime.strptime(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S")
time_diff = datetime.timedelta(days=30)
参考网站:https://stackoverflow.com/questions/26718664/how-to-compare-two-dates-in-jinja23 模板空格去除
参考网站:http://greyli.com/flask-template-engine-jinja2-syntax-introduction/
七、database插件
databases特性
http://datatables.club/reference/option/"lengthChange":false, //隐藏左上角Length页面 "searching": false, //隐藏右上角本地搜索 "info": false, //隐藏左下角提示信息测试界面如图:
同时,这是bootstrap风格的分页,变成图中界面的相关js和css文件为:
js文件<script src="{{ url_for('static', filename='assets/jquery-datatables-editable/jquery.dataTables.js') }}">css相关
<link rel="stylesheet" href="{{ url_for('static', filename='assets/jquery-datatables-editable/datatables.css') }}"/> <style> .table-striped > tbody > tr:nth-of-type(odd) { background-color: #ffffff; } .table-bordered { border: none; } table.table-bordered th:last-child, table.table-bordered td:last-child { border-top-width: 0; border-right-width: 0; } div.dataTables_paginate ul.pagination { margin: 2px 0; margin-top: 15px; white-space: nowrap; } </style> 页内显示,将tr设置一个数据并弄成隐藏,这样才能达到如图示的效果。要是打算在此界面倒序排列数据的话,记得在script部分将排序关闭。"ordering": false <thead> <tr> <th class="text-center" style="display: none">g </th> </tr> </thead>2 控制Datatables元素的位置(dom)
为了调整左上(lengthChange),右上(searching),左下(info),右下(分页)的具体位置,本小节参考官网资料总结了如何调整这四个小部件的样式和位置。先上一段官网资料:
l - Length changing 改变每页显示多少条数据的控件
f - Filtering input 即时搜索框控件
t - The Table 表格本身
i - Information 表格相关信息控件
p - Pagination 分页控件
r - pRocessing 加载等待显示信息
< > - div elements 代表一个div元素 <div></div>
<”#id” > - div with an id 指定了id的div元素 <div id=’id’></div>
<”class” > - div with a class 指定了样式名的div元素 <div class=’class’><d/iv>
<”#id.class” > - div with an id and class 指定了id和样式的div元素 <div id=’id’ class=’class’></div>
我在registration/tinfo.html下的设置为:$('#datatable-editable').DataTable({ dom: 't<"#filter.pull-left"f><"pull-right"p><"clear">', # 这段才是最重要的 "oLanguage": { "sLengthMenu": "每页显示 _MENU_ 条记录", "sZeroRecords": "抱歉, 没有找到", "sInfo": "从第 _START_ 条到第 _END_ 条/共 _TOTAL_ 条数据", "sInfoEmpty": "没有数据", "sInfoFiltered": "(从 _MAX_ 条数据中检索)", "sZeroRecords": "没有检索到数据", "sSearch": "查找: ", "oPaginate": { "sFirst": "首页", "sPrevious": "前一页", "sNext": "后一页", "sLast": "尾页" } }, "iDisplayLength": 6, {#"lengthMenu": [5, 10, 15, 20],#} "lengthChange": false, //隐藏左上角Length页面 "searching": true, //隐藏右上角本地搜索 "info": false, //隐藏左下角提示信息 "pagingType": "full_numbers", "ordering": false {#取消全局排序#} });
八、summernote插件
本内容为说明从数据库读取内容至文本框,之前有一部分内容为从数据库读取内容至网页,文章为BootStrap,使用过程中的一些get点(个人向)。特别提示:在forms.py中,用textarea来配合summernote的样式生成编辑器。这样做的目的是为了将数据通过form表单存储到数据库中。代码如下,重要部分用红色标注:
body部分:<div class="form-group"> {{ form.info.label(class="col-md-2 control-label") }} <div class="col-md-10"> {{ form.info }} <input id="content" value="{{ newsinfo.content }}" type="hidden"> </div> </div>script部分:
jQuery(document).ready(function () { $('.summernote').summernote({ lang: 'zh-CN', height: 200, // set editor height minHeight: null, // set minimum height of editor maxHeight: null, // set maximum height of editor focus: true }); $('.summernote').code($("#content").val()); });以上代码均在newsinfo_edit.html中
参考网站:http://www.voidcn.com/article/p-ykfcvfui-bop.html
九、pycharm相关
Please-Specify-a-different-SDK-Name
此问题发生在我卸载了一个模块后,pycharm的项目出现了无法启动的现象,经过搜索得知,是出现了2个一样的解释器,删除一个即可。参考网站如下:
https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000792670–solved-Project-Interpreter-Error-Please-Specify-a-different-SDK-Name
十、sweet-alert插件
sweet-alert的二次定制,算是了解到了一点点此插件的用法,代码如下:
$('#sa-warning').click(function () { swal({ title: "确认报名?", text: "您想要报名此次考试么?", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "是的,我要报名", cancelButtonText: "取消", closeOnConfirm: false }, function (isConfirm) { if (isConfirm) { swal({ title:"报名成功!", text:"请去个人中心查看详细信息!", type:"success", confirmButtonText: "OK" }, function (flag) { if(flag){ location.href = "{{ url_for('registration.admission_generate', trinfo_id=trinfo.id, user_id=session["user_id"]) }} "; } }); } }); });
十一、flask-mail邮箱配置及使用
flask-mail配置和使用,代码如下:
init.pyfrom flask_mail import Mail # 从flask-mail中导入此模块 app.config.update(dict( DEBUG=False, MAIL_SERVER='smtp.mxhichina.com', # 我用的是阿里云企业邮箱 MAIL_PORT=465, MAIL_USE_SSL=True, MAIL_USERNAME='你的邮箱', # 此处是[email protected],即下方的sender值 MAIL_PASSWORD='你的邮箱密码', # MAIL_DEFAULT_SENDER='From: [email protected]' )) mail = Mail(app) # 将app注册到此模块中views.py
from app import app, db, mail # 将mail导入 from threading import Thread # 将线程导入,目的是为了异步发送邮件 def advice(): form = AdviceForm() # 我自己的form,可以无视 if form.validate_on_submit(): data = form.data now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") msg = Message("在 " + now + " 收到来自" + data["email"] + "的建议!", sender="[email protected]") # 这才是重要的 msg.add_recipient(data["email"]) # 这才是重要的 msg.html = "<h1>邮件功能测试<br>" + data["content"] + "<br><h1>" + data["name"] + "" # 这才是重要的 thr = Thread(target=send_async_email, args=[app, msg]) # 这才是重要的 thr.start() # 这才是重要的 flash("您的建议我们已经收到,谢谢!", "OK") return redirect(url_for("registration.advice")) return render_template("registration/advice.html", form=form)msg.add_recipient(data[“email”]) :此处是为了将表单中的邮箱加入收件人
截图如下:
参考网站:http://www.pythondoc.com/flask-mail/
参考网站:http://blog.****.net/u012246342/article/details/52313051
十二、morris.js插件
html部分代码如下:
<div id="bar_chart" style="height: 300px;">js代码如下:new Morris.Bar({ // ID of the element in which to draw the chart. element: 'bar_chart', // Chart data records -- each entry in this array corresponds to a point on // the chart. data: [ {% for chart in chart_list %} {day: '{{ chart[0] }}', value: {{ chart[1] }} }, {% endfor %} ], 数据库的数据 // The name of the data record attribute that contains x-values. xkey: 'day', // A list of names of data record attributes that contain y-values. ykeys: ['value'], // Labels for the ykeys -- will be displayed when you hover over the // chart. labels: ['费用'], barColors: ["#61adc0"], hideHover: true });截图:
参考网站:http://morrisjs.github.io/morris.js/#your_first_chart
十三、Highcharts插件
html部分代码如下:
<div id="myChart2" style="height: 300px;">js代码如下:Highcharts.chart('myChart2', { title: { text: '' }, xAxis: { categories: [ {% for chart in chart_list %} "{{ chart[0] }}", {% endfor %} ], title: { text: false } }, yAxis: { title: { text: false }, }, legend: { layout: 'vertical', align: 'right', verticalAlign: 'middle' }, series: [{ name: '费用', data: [ {% for chart in chart_list %} {{ chart[1] }}, {% endfor %} ] }], responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' } } }] } });截图:
参考网站:https://www.highcharts.com/demo/line-basic
参考网站:https://www.highcharts.com/demo
参考网站:http://www.runoob.com/highcharts/highcharts-configuration-syntax.html
参考网站:https://www.hcharts.cn/docs/basic-color
十四、Arrow-一个最好用的日期时间Python处理库
参考网站:http://arrow.readthedocs.io/en/latest/
参考网站:https://www.jianshu.com/p/c878bb1c48c1