一、wtforms

类比Django的Form组件
Form组件的主要应用是帮助我们自动生成HTML代码和做一些表单数据的验证

flask的wtforms用法跟Form组件大同小异
参考文章:https://www.cnblogs.com/Zzbj/p/9966753.html

下载安装
pip install wtforms

1、wtforms使用介绍

1. wtforms支持的字段和验证函数
原文:https://blog.csdn.net/wuqing942274053/article/details/72510920

WTForms支持的HTML标准字段

字段类型 说明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密码文本字段
HiddenField 隐藏文本字段
DateField 文本字段,值为datetime.date格式
DateTimeField 文本字段,值为datetime.datetime格式
IntegerField 文本字段,值为整数
DecimalField 文本字段,值为decimal.Decimal
FloatField 文本字段,值为浮点数
BooleanField 复选框,值为True和False
RadioField 一组单选框
SelectField 下拉列表
SelectMultipleField 下拉列表,可选择多个值
FileField 文件上传字段
SubmitField 表单提交按钮
FormField 把表单作为字段嵌入另一个表单
FieldList 一组指定类型的字段

WTForms验证函数

验证函数 说明
Email 验证电子邮件地址
EqualTo 比较两个字段的值,常用于要求输入两次密码进行确认的情况
IPAddress 验证IPv4网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其他验证函数
Required 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选列表中

2. wtforms类的属性和方法
属性:
data
  包含每个字段的数据的字典

errors
  包含每个字段的错误列表的DECT。如果没有验证表单,或者没有错误,则为空。

meta
  这是一个包含各种配置选项以及自定义表单行为的能力的对象。有关可以使用类元选项自定义的内容的更多信息,请参见类元文档。

方法:
validate():通过在每个字段上调用Value来验证表单,将任何额外的Form.Value_<field name>验证器传递给字段验证器。
populate_obj(obj):使用表单字段中的数据填充传递的obj的属性。
__iter__():按创建顺序迭代表单字段。
__contains__(name):如果指定的字段是此表单的成员,则返回True。

例如:

form_obj = wtform(request.form)
if form_obj.validate():
# 包含每个字段的数据的字典
print(form_obj.data)
# 这是一个包含各种配置选项以及自定义表单行为的能力的对象
print(form_obj.meta)
return "注册成功"
# 包含每个字段的错误列表的DECT。如果没有验证表单,或者没有错误,则为空。
print(form_obj.errors)

字段的基类:

label 字段的标签
validators 验证器 -验证的序列时要调用验证被调用
default 如果未提供表单或对象输入,则分配给字段的默认值
widget 如果提供,则覆盖用于呈现字段的窗口小部件
render_kw 设置字段的额外参数,提供一个字典
   
filters 按进程在输入数据上运行的一系列过滤器。
description 字段的描述,通常用于帮助文本
id 用于字段的id。表单设置了合理的默认值,您不需要手动设置。
   
_form 包含此字段的表单。在施工期间,它由表格本身传递。你永远不应该自己传递这个值。
_name 此字段的名称,由封闭表单在构造期间传递。你永远不应该自己传递这个值
_prefix 前缀为此字段的表单名称的前缀,在构造期间由封闭表单传递。
_translations 提供消息翻译的翻译对象。通常在施工期间通过封闭的形式通过。
_meta 如果提供,这是表单中的'meta'实例。你通常不会自己通过

2、基本的使用

1. MyForms.py 定义Form表单的类

from wtforms import Form, widgets
from wtforms.fields import simple, core, html5 # 使用wtforms的类必须要继承它的Form类
# simple:普通字段 core:核心字段 html5:H5新增的字段 class RegisterForm(Form):
username = simple.StringField(
label='用户名',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
# widget插件,可以把这个字段设置成其他type类型
widget=widgets.TextArea()
)
pwd = simple.PasswordField(
label='密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'}
)
re_pwd = simple.PasswordField(
label='确认密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'}, )

2. 视图

from flask import Blueprint, render_template
from FlaskPlug.utils.MyForms import RegisterForm userBlue = Blueprint("userBlue", __name__) @userBlue.route('/register')
def register():
# 实例化form
form_obj = RegisterForm()
return render_template('register.html', form_obj=form_obj)

3. HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h2 style="margin-top: 50px;margin-bottom: 30px;text-align: center">欢迎注册</h2>
<form action="" method="POST" novalidate class="form-horizontal">
{% for field in form_obj %}
<div class="form-group">
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
</div>
</div> </body>
</html>

3、验证

3-1、基本验证

步骤
  1. 在Form类中增加验证信息
  2. 在视图中做数据的校验 并且页面展示错误信息

1. MyForms.py 定义Form表单的类

from wtforms import Form, widgets, validators
from wtforms.fields import simple, core, html5 class RegisterForm(Form):
username = simple.StringField(
label='用户名',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
# 可以定义多个校验规则
validators=[
# DataRequired字段必填
validators.DataRequired(message='用户名不能为空'),
# length字段的长度限制
# message:用户填写错误时的错误信息
validators.length(min=2, max=8, message='长度必须在2-8之间')
],
# widget=widgets.TextArea()
)
pwd = simple.PasswordField(
label='密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间')
],
)
re_pwd = simple.PasswordField(
label='确认密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间'),
# EqualTo:校验两个字段的值是否相等
validators.EqualTo('pwd', message='两次密码不一致')
],
)
phone = simple.StringField(
label='手机号码',
validators=[
validators.Regexp(regex="^1[3-9][0-9]{9}$",message='手机格式不正确')
] )

2. 视图

from flask import Blueprint, render_template, request
from FlaskPlug.utils.MyForms import RegisterForm
from FlaskPlug.models import User userBlue = Blueprint("userBlue", __name__) @userBlue.route('/register', methods=['GET', 'POST'])
def register():
# 实例化form
form_obj = RegisterForm()
if request.method == "POST":
# 把用户提交上来的数据放入Form表单中实例化
form_obj = RegisterForm(request.form)
# validate方法会去校验用户提交上来的数据
if form_obj.validate():
# 验证通过可以写入数据库,这里演示,不写入
# 验证通过的数据都保存在data这个大字典里面
# username = form_obj.data.get('username')
# password = form_obj.data.get('pwd')
# user_obj = User(username=username, password=password)
# db.session.add(user_obj)
# db.session.commit()
# db.session.close()
return "注册成功"
return render_template('register.html', form_obj=form_obj)

3. HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h2 style="margin-top: 50px;margin-bottom: 30px;text-align: center">欢迎注册</h2>
<form action="" method="POST" novalidate class="form-horizontal">
{% for field in form_obj %}
<div class="form-group">
{{ field.label }}
{{ field }} <span style="color: red">{{ field.errors[0] }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
</div>
</div> </body>
</html>
3-2、自定义校验规则
from wtforms import Form, validators, ValidationError
from wtforms.fields import simple def check_username(form, field):
if len(field.data) < 2:
raise ValidationError('错了,嘿嘿') class TestForm(Form):
username = simple.StringField(
label='用户名',
validators=[check_username, ]
)
3-3、利用钩子函数进行校验
局部钩子函数: validate_字段名,接收两个参数(form, field),后端调用validate()校验函数的时候触发
form: wtforms类的实例
field: 字段对象,可以通过field.data获取前端传过来的该字段的数据,不是字典 全局钩子函数:validate, 接收self参数,self.data代表前端表单传过来的所有数据,是一个字典 from wtforms import Form, validators, ValidationError
from wtforms.fields import simple class TestForm(Form):
username = simple.StringField(
label='用户名',
)
password = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间')
]
) # 局部钩子函数
def validate_username(form, field):
print(field.data) # 张三
if len(field.data) < 2:
raise ValidationError('用户名至少两位字符') # 全局钩子函数
def validate(self):
print(self.data) # {'username': '张三', 'password': '12345678'}
for key, value in self.data.items():
print(value)

4、拓展字段core/html5

from wtforms import Form, widgets, validators
from wtforms.fields import simple, core, html5 class RegisterForm(Form):
username = simple.StringField(
label='用户名',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
# 可以定义多个校验规则
validators=[
# DataRequired字段必填
validators.DataRequired(message='用户名不能为空'),
# length字段的长度限制
# message:用户填写错误时的错误信息
validators.length(min=2, max=8, message='长度必须在2-8之间')
],
# widget=widgets.TextArea()
)
pwd = simple.PasswordField(
label='密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间')
],
)
re_pwd = simple.PasswordField(
label='确认密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间'),
# EqualTo:校验两个字段的值是否相等
validators.EqualTo('pwd', message='两次密码不一致')
],
)
phone = simple.StringField(
label='手机号码',
validators=[
validators.Regexp(regex="^1[3-9][0-9]{9}$",message='手机格式不正确')
] )
# H5新增的标签email
email = html5.EmailField(
label='邮箱',
validators=[
validators.DataRequired(message='邮箱不能为空.'),
],
widget=widgets.TextInput(input_type='email'),
)
# 核心字段core,单选框
gender = core.RadioField(
label='性别',
choices=((1, '男'), (2, '女')),
# 前端传过来的数据是字符串类型,coerce可以把穿过来的数据转换类型
# 因为数据库存的1是int类型,前端选择"男",传过来的是字符串1
coerce=int,
default=1
)
# 单选下拉菜单
city = core.SelectField(
label='城市',
choices=(('sz', '深圳'), ('gz', '广州'), )
)
# 多选下拉菜单
hobby = core.SelectMultipleField(
label='爱好',
choices=(
(1, '美女'),
(2, 'xiong'),
),
)
favor = core.SelectMultipleField(
label='喜好',
choices=(
(1, '篮球'),
(2, '足球'),
),
# 把多选下拉菜单设置成列表
widget=widgets.ListWidget(prefix_label=False),
option_widget=widgets.CheckboxInput(),
coerce=int,
default=[1, 2]
) def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
# 从数据库获取数据 做到实时更新
# self.favor.choices = ORM操作
# 这里演示一下更改
self.favor.choices = ((1, '篮球'), (2, '足球'), (3, '羽毛球'))

5、实现csrf_token

1.Form类

from flask import request
from wtforms import Form
from wtforms.csrf.core import CSRF
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets
from hashlib import md5 # 自定义CSRF类,重写CSRF的三个方法
class MyCSRF(CSRF):
"""
Generate a CSRF token based on the user's IP. I am probably not very
secure, so don't use me.
""" def setup_form(self, form):
# 获取class Meta里设置的一些值
self.csrf_context = form.meta.csrf_context()
self.csrf_secret = form.meta.csrf_secret
# 调用父类的setup_form方法
return super(MyCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token):
# 使用md5加密,生成唯一token
gid = self.csrf_secret + self.csrf_context
token = md5(gid.encode('utf-8')).hexdigest()
return token def validate_csrf_token(self, form, field):
# 校验token
print(field.data, field.current_token)
if field.data != field.current_token:
raise ValueError('Invalid CSRF') class RegisterForm(Form):
username = simple.StringField(
label='用户名',
render_kw={'class': 'form-control'},
widget=widgets.TextInput(),
validators=[
validators.DataRequired(message='用户名不能为空'),
validators.length(min=2, max=8, message='长度必须在2-8之间')
]
)
password = simple.PasswordField(
label='密码',
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间')
]
)
re_pwd = simple.PasswordField(
label='确认密码',
# 给这个字段添加样式
render_kw={'class': 'form-control'},
validators=[
validators.DataRequired(message='密码不能为空'),
validators.length(min=8, max=16, message='长度必须在8-16之间'),
validators.EqualTo('password', message='两次密码不一致')
]
)
phone = simple.StringField(
label='手机号码',
validators=[
validators.Regexp(regex="^1[3-9][0-9]{9}$", message='手机格式不正确')
] ) class Meta:
# -- CSRF
# 是否自动生成CSRF标签
csrf = True
# 生成CSRF标签name
csrf_field_name = 'csrf_token' # 自动生成标签的值,加密用的csrf_secret
csrf_secret = '一库'
# 自动生成标签的值,加密用的csrf_context
csrf_context = lambda x: request.url
# 生成和比较csrf标签
csrf_class = MyCSRF # -- i18n
# 是否支持本地化
# locales = False
locales = ('zh', 'en')
# 是否对本地化进行缓存
cache_translations = True
# 保存本地化缓存信息的字段
translations_cache = {}

2.models

class User(db.Model):
__tablename__ = 'user' id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(32), nullable=False)
password = db.Column(db.String(32), nullable=False)
phone = db.Column(db.String(32))

3.视图

from flask import request, views, session, render_template
from flask_demo.home.models.home_model import *
from flask_demo import db
from flask_demo.home.forms.home_forms import RegisterForm class RegisterView(views.MethodView):
def get(self):
form_obj = RegisterForm()
return render_template('register.html', form_obj=form_obj) def post(self):
form_obj = RegisterForm(request.form)
if form_obj.validate():
user_dict = {}
user_dict['username'] = form_obj.data.get('username')
user_dict['password'] = form_obj.data.get('password')
user_dict['phone'] = form_obj.data.get('phone')
user_obj = User(**user_dict)
db.session.add(user_obj)
db.session.commit()
db.session.close()
return "注册成功"
return render_template('register.html', form_obj=form_obj)

4.HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h2 style="margin-top: 50px;margin-bottom: 30px;text-align: center">欢迎注册</h2>
<form action="" method="POST" novalidate class="form-horizontal">
{{ form_obj.csrf_token }}
<div class="form-group">
{{ form_obj.username.label }}
{{ form_obj.username }}
<span style="color: red">{{ form_obj.username.errors[0] }}</span>
</div>
<div class="form-group">
{{ form_obj.password.label }}
{{ form_obj.password }}
<span style="color: red">{{ form_obj.password.errors[0] }}</span>
</div>
<div class="form-group">
{{ form_obj.re_pwd.label }}
{{ form_obj.re_pwd }}
<span style="color: red">{{ form_obj.re_pwd.errors[0] }}</span>
</div>
<div class="form-group">
{{ form_obj.phone.label }}
{{ form_obj.phone }}
<span style="color: red">{{ form_obj.phone.errors[0] }}</span>
</div>
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
</div>
</div>
</body>
</html>

二、基于Flask的文件上传Demo

"""
文件上传完后,进行代码的统计
app.config.root_path: 项目的根路径
os.walk:
遍历你给的路径下的所有文件(会递归遍历)
每次循环的根文件夹的路径,文件夹的名字组成的列表,和文件组成的列表
dirpath, dirnames, filenames
zipfile: 压缩解压文件的模块
shutil: 也是压缩解压文件的模块,还能移动啥的
""" from flask import Blueprint, request, render_template
from flask import current_app as app
import shutil
from uploadCode.models import CodeRecord
from uploadCode import db
import os
import time uploadBlue = Blueprint('uploadBlue', __name__) # zip包上传
@uploadBlue.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == "GET":
return render_template("upload.html", error="")
# 先获取前端传过来的文件
file = request.files.get("zip_file")
# 判断是否是zip包
zip_file_type = file.filename.rsplit(".", 1)
if zip_file_type[-1] != "zip":
return render_template("upload.html", error="文件必须是zip包")
# 解压路径
upload_path = os.path.join(app.config.root_path, "files", zip_file_type[0]+str(time.time()))
print(upload_path)
# 解压前端传过来的文件file到upload_path这个路径
shutil._unpack_zipfile(file, upload_path)
# 遍历保存的文件夹得到所有.py文件
file_list = []
for (dirpath, dirnames, filenames) in os.walk(upload_path):
for filename in filenames:
file_type = filename.rsplit(".", 1)
if file_type[-1] != "py":
continue
file_path = os.path.join(dirpath, filename)
file_list.append(file_path)
# 打开每个文件读取行数
sum_num = 0
for path in file_list:
with open(path, mode="rb") as f:
for line in f:
if line.strip().startswith(b"#"):
continue
sum_num += 1
# 得到总行数去保存数据库
return str(sum_num)

1. upload.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
请上传你的代码: <input type="file" name="zip_file">
<button type="submit">提交</button>
{{error}}
</form> </body>
</html>

2. HTML代码

三、柱状图

参考文档Echarts:http://echarts.baidu.com/

1、使用Echarts步骤

1. 下载它需要的依赖包
2. 点击某个Demo-->Download
3. 参考着Demo去实现你的需求

2、注意

从后端传数据到前端的时候,因为展示的柱状图需要后端的数据,
而如果把数据直接在JS中使用,会出现一些问题,
因此,我们可以使用一个标签,给这个标签设置属性从而获取从后端传过来的数据,
然后在JS中获取这个标签的属性值,就可以拿到后端的数据了,
但是从属性获取的数据已经被转化成字符串了,我们这时可以使用eval()方法,
把数据类型重新转换回来。

3、Demo

from flask import Blueprint, request, render_template
from uploadCode.models import CodeRecord
from uploadCode import db # 柱状图
@uploadBlue.route("/")
def index():
# 展示用户提交代码柱状图
queryset = db.session.query(CodeRecord).all()
date_list = []
num_list = []
for obj in queryset:
date_list.append(str(obj.upload_date))
num_list.append(obj.code_nums)
return render_template("index.html", date_list=date_list, num_list=num_list)

1. Demo.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/echarts.common.min.js"></script>
</head>
<body>
<div id="container" style="height: 400px"></div>
<!--用一个标签获取从后端传过来的数据-->
<div id="info" date_list="{{date_list}}" num_list="{{num_list}}"></div>
<script>
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
let infoEle = document.getElementById("info");
let date_list = infoEle.getAttribute("date_list");
let num_list = infoEle.getAttribute("num_list");
option = null;
app.title = '坐标轴刻度与标签对齐'; option = {
color: ['#3398DB'],
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis : [
{
type : 'category',
data : eval(date_list),
axisTick: {
alignWithLabel: true
}
}
],
yAxis : [
{
type : 'value'
}
],
series : [
{
name:'直接访问',
type:'bar',
barWidth: '60%',
data: eval(num_list) // 重新计算一下这个字符串,转成原本的数据类型
}
]
};
;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
</script>
</body>
</html>

2. HTML代码(根据官方Demo修改一下)

Flask插件wtforms、Flask文件上传和Echarts柱状图的更多相关文章

  1. 【Flask】 结合wtforms的文件上传表单

    表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...

  2. flask插件系列之flask_uploads上传文件

    前言 flask可以实现上传文件和下载文件的基本功能,但如果想要健壮的功能,使用flask_uploads插件是十分方便的. 安装 pip install flask_uploads 基本使用 # e ...

  3. 结合bootstrap fileinput插件和Bootstrap-table表格插件,实现文件上传、预览、提交的导入Excel数据操作流程

    1.bootstrap-fileinpu的简单介绍 在前面的随笔,我介绍了Bootstrap-table表格插件的具体项目应用过程,本篇随笔介绍另外一个Bootstrap FieInput插件的使用, ...

  4. HTML5文件上传器,纯脚本无插件的客户端文件上传器---Uploader 文件上传器类

    概述 客户端完全基于JavaScript的 浏览器文件上传器,不需要任何浏览器插件,但需要和jQuery框架协同工作,支持超大文件上传,其算法是将一个超大文件切片成N个数据块依次提交给服务 端处理,由 ...

  5. ajaxFileUpload.js插件支持多文件上传的方法

    前提条件:ajaxFileUpload.js插件多文件上传步骤:1.修改源码,(源码只支持单个文件的上传):复制代码 代码如下: //修改前代码------- //var oldElement = j ...

  6. BootStrap FileInput 插件实现多文件上传前端功能

    <!DOCTYPE html> <html> <head> <title>文件上传</title> <meta charset=&qu ...

  7. 使用flask实现简单的文件上传

    from flask import Flask, redirect, render_template, request, url_forfrom werkzeug.utils import secur ...

  8. ajax+php (jquery.form插件)实现异步文件上传

    <!DOCTYPE html> <html lang="CN"> <head> <title>upload model</ti ...

  9. flask完成文件上传功能

    在使用flask定义路由完成文件上传时,定义upload视图函数 from flask import Flask, render_template from werkzeug.utils import ...

随机推荐

  1. 20190322-a标签、img标签、三列表、特殊字符实体、表格

    目录 1.a标签 a标签的属性 锚点 2.img标签 img标签的属性 图像热区 3.三列表 有序列表(Ordered List)     ol>li 无序列表(Unordered List)  ...

  2. HTML的概念和三大基石以及标准文档结构

    HTML的概念: 概念:  HTML:超文本标记语言 作用:  需要将java在后台根据用户请求处理的请求结果在浏览器中显示给用户.  在浏览器中数据需要使用友好的格式展示给用户.  HTML是告诉浏 ...

  3. 小tips:JS之for in、Object.keys()和Object.getOwnPropertyNames()的区别

    for..in循环 使用for..in循环时,返回的是所有能够通过对象访问的.可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例.这里需要注意的是使用for-in返回的属性因各个浏览器厂 ...

  4. Windows7 WIN 7 64位 环境编译6sv2.1版本的大气传输模型

    从来没见过Fortran...这次为了添加国产卫星光谱响应的支持,只能从零开始肯了. 6S模型主页:http://6s.ltdri.org/index.html. 下载最新的2015年更新的6SV2. ...

  5. 从头认识一下docker-附带asp.net core程序的docker化部署

    从头认识一下docker-附带asp.net core程序的docker化部署 简介 在计算机技术日新月异的今天, Docker 在国内发展的如火如荼,特别是在一线互联网公司, Docker 的使用是 ...

  6. 基本的CRUD操作

    导入包---实体类------数据库连接----数据库操作----service层数据操作----网页对service层可视化实现 model package com.ij34.model; publ ...

  7. ZYNQ EMIO使用及可重用封装

    为了快速实现算法板级验证,PC端需要通过JTAG或以太网与FPGA形成通路.最简单便捷的方案是利用协议栈芯片,用户可以无视底层,利用简单的SPI协议读写寄存器实现复杂的TCP UDP等网络协议.当然带 ...

  8. mysql导出表的字段及相关属性

    需要导出数据库中表的字段及属性,制成表格保存到word中 首先找到要导的库, 在查询页面输入sql SELECT COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA_TYPE ...

  9. JS第二部分--DOM文档对象模型

    一.DOM的概念 二.DOM可以做什么 三.DOM对象的获取 四.事件的介绍 五.DOM节点标签样式属性的操作 六.DOM节点对象对值的操作 七.DOM节点-标签属性的操作(例如id class sr ...

  10. gulp结合Thinkphp配置

    gulpfile.js文件 /*! * gulp * $ npm install gulp gulp-ruby-sass gulp-cached gulp-uglify gulp-rename gul ...