FLASK

一、概述

flask是一个基于python并依赖于Jinja2模板引擎和WerkZeug WSGI(Web Server Gatewey InterFace.web)服务的框架

WSGI:服务网关接口,提供处理网络请求相关的功能

hello world

from flask import Flask

# 创建flask的程序实例
app = Flask(__name__) @app.route('/') # 路由配置 # 视图函数
def index():
return "<h1>欢迎访问</h1>" # 启动服务
if __name__ == "__main__":
app.run(debug=True)

二、 定义路由

路由是为了匹配用户的请求地址,会自动执行视图函数。视图函数中必须有返回值,返回字符串显示到响应的页面中。

2. 无参数

定义路由

@app.route('/地址')

定义视图函数

def funcName():
return "" # 响应到页面的内容

例如:

@app.route("/") # '/'表示根路径
def index(): #匹配到路径后执行的视图函数
return "首页"

3. 带参数

变量:<变量名>

@app.route("/login/<name>")
def login(name):
return "欢迎%s登陆"%name

如需要设置默认路由,则在视图函数中传参直接设置def login(name="Chancey")

还有一种方式,就是在路由装饰器中传入一个字典@app.route("/login/<name>",defaults={"name":"游客"})

4. 类型转换器

缺省:字符串,不能包含'/'

int:转换整数 float:转换小数 path:字符串,运行包含'/'

使用:@app.route('/show/<int:num>')在路径中直接转换

例如

配置路由:/calaute/<number1>/<number2>,视图函数中接收参数,返回类似于“3 + 5 = 8”

@app.route('/calaute/<num1>/<num2>')
def calaute(num1,num2):
return "%s + %s = %d"%(num1,num2,int(num1)+int(num2))

注意:路径中的参数变量永远是字符串

5. 多个URL

多个URL执行同一个视图函数

@app.route("/")
@app.route("/index")
def index():
return "首页"

例如

定义路由:127.0.0.1:5000/show 127.0.0.1:5000/show/list 127.0.0.1:5000/show/<name>,执行同一个函数,返回相应的内容

@app.route("/show")
@app.route("/show/list")
@app.route("/show/<name>")
def show(name="Chancey"):
return "show %s"% name

如果在app.run()设置host=0.0.0.0

不影响当前虚拟IP(127.0.0.1)

可以让当前局域网中的其他计算机通过内网IP访问服务器

二、模板

模板是一种特殊的HTML文件,Python+HTML网页结构,允许在模板文件中使用变量,定义流程控制。使用模板可以使用视图函数专注于处理业务逻辑,将页面渲染交由模板控制

  • 导入render_template

  • 项目中创建“templates”文件夹,所有模板文件必须存放"template"文件夹下

  • 在视图函数中使用render_template("模板文件"),生成模板字符串,交由浏览器解析

from flask import Flask,render_template

app = Flask(__name__)

@app.route("/info")
def info():
return render_template("01-show.html", name="flask", age=20)

1. 变量代码块

  1. 模板中使用变量

    语法:{{ 变量名(key) }}

  2. 从视图函数中获取相关的变量,传递到模板文件中

    语法:return render_template("模板文件", key1=value1, key2=value2)

    函数中可以传递若干键值对,其中的key名就是在模板文件中使用的变量名

    local()函数,是将当前作用域中的所有局部变量打包成一个字典返回,可以用一个变量接收,然后传递到模板中.

    • 如果变量里面有字典类型的数值,有两种方法取值variable["keyName"]variable.keyName
    • 如果变量里面有列表类型的数值,则直接用list[number]取值

例如:

视图函数中定义变量(name="" age= dic= tub= list= ),将数据传递到模板文件中显示

from flask import Flask, render_template

# 创建实例
app = Flask(__name__) # 定义动物类
class Pet(object):
name = None
def play(self):
return "来和" + self.name + "玩耍吧" @app.route('/show') def show():
name = "Chancey"
age = 18
dic = {
"name":"Waller",
"age":20
}
list = ["开车","保健"]
tup = ("波多","仓井","海翼") # 实例化对象
cat = Pet()
cat.name = "妲己" # locals() 将当前作用域中的局部变量包装成一个字典返回 # key=value
return render_template("01-show.html", d=locals())
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>show</title>
</head>
<body>
<h1>模板文件</h1>
<p>列表、元组、字典都可以使用[key/index]和点语法访问</p>
<p>name:{{ d["name"] }}</p>
<p>age:{{ d.age }}</p>
<p>name:{{ d.dic["name"] }}</p>
<p>宠物名:{{ d.cat.name }}</p>
<p>动作:{{ d.cat.play() }}</p>
</body>
</html>

2. 过滤器

允许模板中的变量在输出之前修改成其他的值,修改显示

  • upper转大写字母
  • lower转小写字母
  • title首字母大写
  • first获取第一个
  • last获取最后一个
  • length获取列表长度
  • default如果变量未赋值,可采用默认值
  • trim去掉字符串两边的空格
  • ....

语法:{{ 变量|过滤器1|过滤器2 }}

<!-- 在python文件视图函数中自行添加s1变量,赋值"   hello world" -->
<p>原版:{{ d.s1 }}</p>
<p>大写:{{ d.s1|upper }}</p>
<p>小写:{{ d.s1|lower }}</p>
<p>首字母大写:{{ d.s1|title }}</p>
<p>获取第一个:{{ d.s1|first }}</p>
<p>获取最后一个:{{ d.s1|last }}</p>
<p>获取长度:{{ d.s1|length }}</p>
<p>去掉两边空格:{{ d.s1|trim }}</p>
<p>未赋值的变量:{{ d.s2|default("默认变量") }}</p>

3. 控制代码块

在模板中书写条件语句和循环语句,使用{% python语句 %}

3.1 if

{% if 条件 %}
条件成立时。允许书写静态标签,也可以书写变量
{% endif %} {% if 条件 %}
条件成立时执行
{% else %}
条件不成立时执行
{% endif %} <!-- 多重分支 -->
{% if 条件1 %}
pass
{% elif 条件2 %}
pass
{% elif 条件3 %}
pass
{% endif %}

例如:

    {% if d.age < 18 %}
<h3>{{ d.age }}岁未成年</h3>
{% elif d.age < 30 %}
<h3>{{ d.age }}岁青成年</h3>
{% elif d.age < 50 %}
<h3>{{ d.age }}岁中成年</h3>
{% else %}
<h3>{{ d.age }}岁老年人</h3>
{% endif %}

3.2 for

{% for 变量 in 可跌对象 %}
{% endfor %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>show</title>
<style>
.c1{
background: red;
}
.c2{
background: orange;
}
.c3{
background: cyan;
}
</style>
</head>
<body>
<table border="2px">
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
{% for item in info %}
<tr
{% if loop.first %}
class = c1
{% elif loop.last %}
class = c2
{% else %}
class = c3
{% endif %}
>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def show():
info = [
{"name":"Chancey","age":18},
{"name":"Waller","age":35},
{"name":"Mary","age":16},
{"name":"Jacob","age":40},
{"name":"William","age":17},
{"name":"Samuel","age":37},
{"name":"Anthony","age":35},
]
return render_template("02-show.html", info=info) if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")

3.3 loop

循环的内部变量loop:直接在内部使用,表示本次循环相关的信息

常用属性:

  • loop.index当前循环的次数,默认从1开始计算
  • loop.index0当前循环的次数,从0开始计算
  • loop.first是否为第一次循环,值为True表示第一次循环
  • loop.last是否为最后一个循环

实例在前边for循环中已使用

4. 静态文件

  • 不与服务器交互的文件都是静态文件(css、js、图片、音频等)

  • 所有静态文件都必须存储在一个名为static的文件夹下,Flask程序会自动查找

  • 静态文件的访问:必须使用/static访问

  • url_for("视图函数名")实现反向解析路由,后边可以跟参数

    url_for("login")根据视图函数解析对应的URL

    url_for("login", uname="chancey", passwd="123456")反向解析带参数的路由

    /login/chancey/123

    /static/css/base.css

    <link rel="stylesheet" href="{{ url_for('static',filename='path') }}>"

5.模板继承

与类的继承相似

如果两个页面中大部分内容与结构都一致,可以采用模板继承

实现:

  • 父模板:指定可以被子模板重写的内容

    {% block 块名 %}
    <h1>父模板</h1>
    {% endblock %}
  • 子模板中继承父模板

    {% extends 父模板名称 %}
  • 子模板中可以重写父模板中指定的块的内容

    {% block 块名 %}
    <h1>子模板</h1>
    {% endblock %}
<!--路由自行配置,不再展示-->
<!-- 01-base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block web_title %}
父模板
{% endblock %}
</title>
</head>
<body>
<h4>
{% block title %}
这里是标题
{% endblock %}
</h4>
<p>
{% block content %}
这里是内容
{% endblock %}
</p>
</body>
</html>
<!--路由自行配置,不再展示-->
<!-- 02-index.html -->
{% extends "02-base.html" %} {% block web_title %}
佛曰
{% endblock %} {% block title %}
佛曰
{% endblock %} {% block content %}
写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱。
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年。
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员。
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员?
{% endblock %}

三、网络请求

利用网络通信协议实现前后端数据交互,常用的网络通信协议:HTTP(S),规定数据的传输格式

1. 请求

1.1 请求消息

客户端向服务端发送的消息

1.2 组成

  1. 请求起始行

    协议、请求方式、资源路径

  2. 请求消息头

    使用kry-value字典的方式存储相关信息

  3. 请求主体

    get请求如果携带数据,以参数的形式直接拼接在URL后边(?key1=value1&key2=value2

    只有POST方式才会有请求主体

2. 响应

2.1 响应信息

服务端接收到请求并且处理之后,返回给客户端的信息(数据)

2.2 组成

  1. 响应起始行

    协议、响应状态码、原因短句

  2. 响应消息头

    描述响应回来的数据,以key:value存储

  3. 响应主体

    保存响应数据

四、Flask中的HTTP

1. requests

在requests对象中封装了所有跟当前请求相关的信息

使用:

  1. 引入:from flask import request

  2. 使用:在视图函数中获取request对象内部的信息

  3. 属性:

    scheme获取此次请求的协议

    method获取请求方式

    args获取GET提交的数据

    form获取POST提交的数据

    cookies获取cookies中保存的数据

    files获取上传的文件

    path获取请求的资源路径(无参数)

    full_path获取请求的资源路径(携带参数)

    url 获取完整的请求地址

    headers

<h2>子模板</h2>
<p>协议:{{ params.scheme }}</p>
<p>请求方式:{{ params.method }}</p>
<p>请求的参数:{{ params.args }}</p>
<p>请求的参数的内容:{{ params.args.uname }}</p>
<p>请求的参数的内容:{{ params.args.age }}</p>
<p>cookies:{{ params.cookies }}</p>
<p>资源路径:{{ params.path }}</p>
<p>资源路径:{{ params.full_path }}</p>
  1. 获取请求中的数据

    获取GET请求中的数据

    request.args["key"]

    request.args.get("key","默认值")

    request.args.getlist("key")适用于一个key对应多个值的情况(复选框)

    print(request.args.get("uname"))
    print(request.args.get("passwd"))
    print(request.args.getlist("hobby"))
    #get当时如果未携带数据,在视图函数中直接读取request.args['']数据,报400

    获取POST请求中的数据

    request.form获取数据字典

    request.form["key"]

    request.form.get("key")

    request.form.getlist('key')


    post即使未携带参数,直接获取字典的值,返回为空

  2. 页面重定向

    由服务器端通知浏览器重新向新的地址发送请求

    引入redirect

    使用函数redirect("重定向地址")

    视图函数中返回return redirect("重定向地址")

  3. 页面源

    当前的请求是从哪一个源地址发起的,保存在请求消息头中("Referer":""

  4. 文件上传

    使用表单控件type="file"向服务器发送文件,因为文件,图片,音频等都是为禁止数据,必须设置表单的提交方式和编码类型

    <form action="" method="post" ectype="multipart/form-data">

    服务器端使用request.files获取上传的文件,返回字典

    例如:

    f = request.files["key"]
    f.save(保存路径)
    @app.route("/add", methods=["GET", "POST"])
    def add():
    if request.method == "GET":
    return render_template("02-add.html")
    else:
    title = request.form["title"]
    type = request.form["type"]
    content = request.form["content"]
    print("标题:%s 类型:%s 内容:%s"%(title, type, content)) # 判断文件上传
    if "userimg" in request.files:
    file = request.files["userimg"]
    file_name = generate_filename(file.filename)
    up_path = generate_upload_path(__file__, "static/upload", file_name)
    print("保存路径:" + up_path)
    return "获取数据成功"
    else:
    return "已存在"

2. response

模型(Models)

模型:根据数据表结构而创建出来的class(一张表一个类,一个字段就是一个属性)

框架:ORM(Object Relational Mapping 对象关系映射)

特征:

  • 数据表到编程类的映射
  • 数据类型的映射
  • 关系映射(将数据库中表与表之间的关系 对应到 编程语言中类与类的关系)

优点:

  • 封装操作提升效率
  • 省略庞大的数据访问层

五、ORM

1. SQLAlchemy

安装:pip install flask-sqlalchemy

导包:from flask_sqlalchemy import SQLAlchemy

配置数据库:app.config['SQLALCHEMY_DATABASE_URI']="MYSQL://用户名:密码@数据地址:端口/数据库名"

创建数据库:create database dbname default charset utf8 collate utf8_general_ci;

数据库自动提交:app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True

from flask import Flask
from flask_sqlalchemy import SQLAlchemy # import pymysql
# pymysql.install_as_MySQLdb() app = Flask(__name__) #连接数据库
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/flaskDB"
#创建SQLAlachemy实例
db = SQLAlchemy(app)
print(db) if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")

上边的代码中,import pymysql \ pymysql.install_as_MySQLdb()可以省略,简写在config中

2. 定义类

2.1 作用

通过编写模型类的方式,让程序自动生成数据表模型类也称为实体类

2.2 语法

# 代码中大写单词均为自定义
class MODELNAME(db.Model):
__tablename__ = "TABLENAME"
COLUMN = db.Column(db.TYPE, OPPTIONS) """
1. MODELNAME 定义模型类名称,参考表名
2. TABLENAME 指定要映射到的表名,如果不存在的话,则创建表
3. COLUMN 属性名,映射到数据表中就是列名
4. TYPE 映射到列的数据类型
5. OPPTIONS 列选项
"""

db.TYPE列类型

OPPTIONS列选项

class Usres(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(20), nullable=False, unique=True)
age = db.Column(db.Integer)
email = db.Column(db.String(120), unique=True) def __init__(self, username, age, email):
self.username = username
self.age = age
self.email - email def __repr__(self):
return "<用户名:%r 年龄:%r 邮箱:%r>"%(self.username, self.age, self.email) #将创建好的实体类映射回数据库
db.create_all()
## 创建Student实体类,表名student
"""
1. id 主键 自增
2. sname 姓名 长度30 不为空
3. sage 年龄 整数
4. isActive 启用状态 bool类型 默认为True
""" ## 创建Teacher类,表名teacher
"""
1. id 主键 自增
2. tname 姓名 长度30 不为空
3. tage 年龄 整数
""" ## 创建Course类,表名course
"""
1. id 主键 自增
2. cname 课程名称 长度30
""" class Student(db.Model):
__tablename__ = "student"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
sname = db.Column(db.String(30), unique=True)
sage = db.Column(db.Integer)
isActive = db.Column(db.Boolean, default="True")
class Teacher(db.Model):
__tablename__ = "teacher"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
tname = db.Column(db.String(30), unique=True)
tage = db.Column(db.Integer)
class Course(db.Model):
__tablename__ = "course"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
cname = db.Column(db.String(30), unique=True)

3. 数据迁移

3.1 定义

将实体类的改动再次映射回数据库

3.2 依赖于第三方库

  • Flask-script

    包:flask_script

    类:Manager

    作用:对项目进行管理(启动项目、增加管理指令)

  • flask-migrate

    包:flask_migrate

    类:Migrate(协调app和db之间的关系)、MigrateCommand(在终端中提供实体类迁移的指令)

3.3 使用

  • 修改app.config

    #指定数据库不追踪
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
    # 指定启动的模式为调试模式
    app.config["DEBUG"] = True
  • 创建管理对象:manage = Manager(app)

  • 启动:manager.run()(但是项目的启动需在终端中执行python demo.py runserver)

在使用了manger启动项目的时候,如需开启相关服务,如debug。。。

在终端启动的时候加参数python demo,py runserver --host 0.0.0.0

配置app.config:app.config["DEBUG"] = True

  • 导入from flask_migrate import Migrate, MigrateCommand
  • 在实体类之前创建migrate = Migrate(app, db)
  • 增加一个子命令manage.add_command("db", MigrateCommand)

3.4 迁移

  • python run.py db init

    作用:执行项目和数据库的初始化操作

    特点:一个项目中只执行一次即可

  • python run.py db migrate

    作用:将编辑好的实体类生成一个中间文件并保存

    特点:只要检测到实体类有更改,就会生成中间文件

  • python run.py db upgrade

    作用:将中间文件映射到数据库

from flask import Flask, request, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/run02"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["DEBUG"] = True
app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True db = SQLAlchemy(app)
manage = Manager(app)
migrate = Migrate(app, db)
manage.add_command("db", MigrateCommand)

六、模型

1. 增

  • 创建实体类对象,并为对象的属性赋值

    user = Users()

    user.username = "Chancey"

    user.age = 30

    user.isActive = True

    user.birthday = "2019-01-01"

  • 将实体对象保存回数据库对象

    db.session.add(user)

    db.session.commit(user)

user = Users(username, age, email)
db.session.add(user)
db.session.commit()

2. 查

2.1 .基于db.session

参数:要查询的列,如果查询多个列的话使用,隔开,如果要查询所有列,参数为实体类名

2.1.1 query()

实例:

  • 查询Users实体类中的id,username

    db.session.query(Users.id, Users.username)

  • 查询Users实体类中所有的列

    db.session.query(Users)

  • 查询Users以及wife实体类所有的列

    db.session.query(Users, Wife)

返回值:返回一个Query对象(SQL语句)

# 返回一个query对象
query = db.session.query(Users.id,Users.uaername)
print(query)
print("type:",type(query))
2.1.2 查询执行函数

作用:在query的基础上得到最终的查询结果

语法:db.session.query(xxx)查询执行函数()

函数:

  • all()

    以列表的方式返回所有的数据

  • first()

    以实体对象的方式返回第一条数据,没有查询到数据则返回None

  • first_or_404()

    效果同上,没查询到结果则响应404

  • count()

    返回查询结果的数量

s = db.session.query(Users.username, Users.age, Users.email).all()
for i in s:
print(i.username, i.age, i.email) user = db.session.query(Users).first()
print(user.username, user.age, user.email) print(db.session.query(Users).count())
2.1.3 查询过滤器函数

作用:在db.session.query()追加条件

语法:db.session.query(xx).执行函数()

函数:

  • filter()各种各样的查询条件均可实现
  • filter_by()只做等值条件判断
  • limit()限定行数
  • offset()指定结果的偏移量
  • order_by()按照指定条件排序
  • group_by()分组查询

返回值:均是query对象

实例:

  • 查询年龄大于25的信息

    db.session.query(Users).filter(Users.age>25).all()

  • 查询id为2的User信息

    db.session.query(Users).filter(Users.id==2).first()

  • 查询idActive为true并且年龄大于30的

    db.session.query(Users).filter(Users.isActive==True).filter(Users.age>30).all()

  • 获取前5条数据

    db.session.query(Users).limit(5).all()

  • 对表中的所有数据按照id倒序排序

    db.session.query(Users).order_by("id desc").all()

(1) or_

导入:from sqlalchemy improt or_

使用:

查询isActive为True或者年龄不小于30的

db.session.query(User).filter(or_(User.isActive==True,User.age>=30)).all()

(2) like

模糊查询like主要使用实体类属性所提供的的like()函数

查询email中包含an的信息

db.session.query(Users).filter(Users.email.like("%an%")).all()

(3) in_

模糊查询in,需要使用实体类提供的属性in_函数完成

查询年龄是30、17、45的*

db.session.query(Users).filter(Users.age.in_([30,17,45])).all()

(4) between

模糊查询between...and...需要使用实体类属性提供的between(值1,值2)

查询年龄在30到45之间的

db.session.query(Users).filter(Users.age.between(30,45)).all()

2.2 基于Models

Models.query.查询过滤(条件参数).查询执行函数()

例如:Users.query.filter(Users.id>3).all()

3. 删除

  • 查询出要删除的实体user = db.session.query(Users).filter_by(id=5).first()
  • 根据所提供的删除方法将信息删除db.session.delete(user)
  • 提交(使用manger可自动提交)db.session.commit()
@app.route('/delete')
def delete_view():
id = request.args.get("id")
user = Users.query.filter_by(id=id).first()
db.session.delete(user) url = request.headers.get("referer", '/query_all')
return redirect(url)

4.修改

  • 保存
user = Users.query.filter_by(id=5).first()
user.uaername = "老杨"
user.passwd = "abcdefg"
return "修改成功"
@app.route('/update', methods=["GET", "POST"])
def update_view():
if request.method == "GET":
id = request.args.get('id') # 获取前端传过来的id
user = Users.query.filter_by(id = id).first() # 根据id查询出对应的实体对象
return render_template("03-update.html", u = user)# 将实体对象放到前端页面显示
else:
id = request.form['id']
username = request.form["username"]
passwd = request.form["passwd"] user = Users.query.filter_by(id = id).first() #查 user.uaername = username # 改
user.passwd = passwd # 改 db.session.add(user) # 保存 return redirect("/info?tiaojian=")

最新文章

  1. HDU 1166 敌兵布阵(线段树单点更新)
  2. Oracle调整联机日志大小
  3. C# 通用上传文件类
  4. OpenSessionInViewFilter与org.springframework.dao.InvalidDataAccessApiUsageException
  5. 浅析PC机串口通讯流控制
  6. 国内最简单的短视频SDK
  7. lucene实战(第二版)学习笔记
  8. 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析
  9. MVC应用程序显示上传的图片
  10. python第四课——线程、进程、协程
  11. Spring知识点回顾(05)bean的初始化和销毁
  12. Python 破解带密码保护的Zip文件
  13. mybatis逆向工程,转载别人的,很清楚
  14. kernel笔记——内核编译与进程管理
  15. HTML5 图片下载
  16. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流
  17. java加减天数
  18. 机器学习之overfiting
  19. iOS 各种控件默认高度(图示)
  20. day12学python 多进程+进程池

热门文章

  1. ssm框架下的文件上传和文件下载
  2. ElasticSearch全文搜索引擎
  3. jquery插件——仿新浪微博限制输入字数的textarea
  4. git删除分支步骤
  5. Transformations 方块转换 USACO 模拟 数组 数学 耐心
  6. Linux - 查看端口的占用情况、找出并杀死占用进程的方法
  7. Dialog 使用详解
  8. 理解nodejs中的stream(流)
  9. resolv.conf文件配置相关的案例
  10. pythonday04数据类型(二)