认识web
URL详解
url是 uniform Resource Locator 的简写,统一资源定位符
一个URL由以下几个部分组成:
scheme://host:port/path/?query-string=xx#anchor
scheme:代表的是访问的协议,一般为http或者https以及ftp等
host:主机名,域名,比如www.google.cn
port:端口号。当你访问一个网站的时候,浏览器默认的使用80端口
path:查找路径。比如www.jianshu.com/trending/now,后面的trending/now就是path
query-string:查找字符串,比如www.baidu.com/s?wd=python,后面的wd=python就是查询字符串
anchor:锚点,后台一般不用管,前端用来做页面的定位的
注意:URL中的所有字符都是ASSCII字符集,如果出现非ASCII字符,比如中文,浏览器会进行编码再传输
笔记:如果使用的是http协议,那么浏览器就会使用80端口去请求这个服务器的资源
如果使用的是https协议,那么浏览器就会使用443端口去请求这个服务器的资源
Web服务器和应用服务器以及web应用框架
Web服务器:负责处理http/https请求,响应静态文件,常见的有Apache,Nginx以及微软IIS
应用服务器:负责处理逻辑的服务器。比如php,python的代码,是不能直接通过nginx这种web服务器来处理的密支那通过应用服务器来处理,常见的应用服务器有uwsgi,tomcat
Web应用框架:一般使用的某种语言,封装了常用的web功能的框架就是web应用框架,flask,Django以及Java中的SSH(Structs2+Spring3+Hibernate3)框架都是web应用框架
第一个flask程序讲解
1.第一次创建项目的时候,要添加flask虚拟环境,添加虚拟环境的时候,一定要选择到python这个执行文件。比如你的flask的虚拟环境的目录在/User/Virtualenv/flask-env/bin/python
2.flask程序代码详细解释
#encdding:utf-8
# 从flask这个框架中导入Flask这个类
from flask import Flask
# 初始化一个Flask对象
# Flask()
# 需要传递一个参数__name__
# 1.方便flask框架去寻找资源
# 2.方便flask插件比如Flask-Sqlalchemy出现错误的时候美好去寻找问题所在的位置
app = Flask(__name__)
# @app.route是一个装饰器
# @开头,并且在函数的上面,说明是装饰器
# 这个装饰器的作用,是做一个url与视图函数的映射
# 127.0.0.1:5000/ -> 去请求hello_world这个函数,然后将结果返回给浏览器
@app.route('/') def hello_world(): return 'Hello World!'
# 如果当前这个文件是作为入口程序运行,那么就执行app.run()
if __name__ == '__main__': # app.run() # 启动一个应用服务器,来接受用户的请求 # while True(): # listen() app.run()
设置debug模式
1.在app.run()中传入一个关键字参数debug,app_run(debug=True),就设置当前项目为debug模式
2.debug模式的两大功能:
*当程序出现问题的时候,可以在页面中看到错误信息和出错的位置
*只要修改了项目中的python文件,程序会自动加载,不需要手动重新启动程序
使用配置文件
1.新建一个`config.py`文件
2.在主app文件中导入这个文件,并且配置到`app` 中,示例代码如下:
```import config
app.config.form_object(config)
3.还有许多其他的参数,都是在这个配置文件中,比如`SECRET_KEY`,`SQLALCHEMY`这些配置,都是在这个文件中
Url传参数
1.参数的作用:可以在相同的url,但可以指定不同的参数,来加载不同的数据
2.在flask中如何使用参数:
@app.route(‘/aritcle/<id>’)
def aritcle(id):
return u’您请求的参数是: %s’ % id
*参数需要放在两个尖括号中
*视图函数中需要放与url同名的参数s
反转URL
1.什么叫做反转url:从视图函数到url的转换叫做反转url
2.反转url的用处:
*在页面重定向的时候,会使用url反转
*在模板中,也会使用url反转
页面跳转和重定向
1.用处:在用户访问一些需要登录的页面的时候,如果用户没有登录,那么可以让他重定向到登录页面
2.代码实现:
from flask import redirect, url_for
Redirect(url_for(‘login')
Flask渲染模板Jinja2模板和传参
1.如何渲染模板
*模板放在`templates`文件夹下
*从`flask`中导入`render_template`函数
*在视图函数中,使用`render_template`函数,渲染模板,注意:只需要填写模板的名字,不需要填写`templates`这个文件夹的路径
2.模板传参
*如果只有一个或者少量参数,直接在`render_template`函数中添加关键字参数就可以了。
*如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后再`render_template`中使用2个*,把字典转换成关键字传递进去,
这样的代码更加方便管理和使用
3.在模板中如果要使用一个变量,语法是:`{{ params }}`
4.访问模型中的属性或者是字典,可以通过`{{ params.property}}`或者是使用{{ params[‘property']}}都是可以的
If判断
1.语法
{% if XXX %}
{% else %}
{% endif %}
过滤器(有很多去官网)
1.介绍和语法
*介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来。作用的对象是变量
*语法:
{{ avater|default(‘xxx’)}}
2.default过滤器:如果当前变量不存在,这个时候可以指定默认值
3.length过滤器:求列表或者字符串或者字典或者元组的长度
{{ list|length }}
4.常用的过滤器(自己百度)
继承和block(用于前端页面)
1.继承作用和语法
*作用:可以把一些公共的代码放在父模板中,避免每个模板写同样的代码
*语法
{% extends ‘base.html' %}
2.block实现
*作用:可以让子模板实现一些自己的需求,父模板需要提前定义好
*注意点:子模板中的代码,必须放在block块中
URL链接:
使用`url_for(视图函数名称)`可以反转url
加载静态文件
1.语法`url_for(’static’, filename=‘路径’)`
2.静态文件,flask会从`static`文件夹中开始寻找,所以不需要再写`static`这个路径
3.可以加载`css`,`js`,`Image`....所有的静态文件
<link rel=“stylesheet” href=“{{ url_for(’static’, filename=‘css/index.css’) }}”
<script src=“{{ url_for(’static’, filename=‘js/index.js’) }}”
<img src=“{{ url_for(’static’, filename=‘images/index.png')}}"
Flask-SQLAlchemy的介绍
1.ORM: Object Relationship Mapping (模型关系映射)
2.flask-sqlalchemy是一套ORM框架
3.ORM的好处:可以让我们操作数据库跟操作对象是一样的,非常方便,因为一个表就抽象成一个类,一条数据就抽象成该类的一个对象。
建库 create database db_demo1 charset utf8;
Flask-SQLAlchemy的使用
1.初始化和设置数据库配置信息
*使用flask_sqlalchemy中的SQLAlchemy进行初始化
From flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
2.设置配置信息:在’config.py’文件中添加以下配置信息
#mysql+mysqldb://username:password@host:port/database DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = '123' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'db_demo1' SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8 ".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE) SQLALCHEMY_TRACK_MODIFICATIONS = False
3.在主app文件中,添加配置文件:
From flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app)
4.做测试
db.create_all()
如果没有报错,说明配置没有问题。
SQLAlchemy的增删改查
1.增
article1 = Article('111',2222) db.session.add(article1) db.session.commit()
2.删
# 删 # 先查后删再提交 article2 = Article.query.filter(Article.title == 'aaa').first() db.session.delete(article2) db.session.commit()
3.改
# 改 # 先查后改再提交 article2 = Article.query.filter(Article.title == '111').first() article2.title = 'aaa' db.session.commit()
4.查
# 查 article2 = Article.query.filter(Article.title == 'aaa').first() if article2: print article2.title,article2.content
【**重点**】
Flask-SQLAlchemy外键及其关系
1.外键
#用户表
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(100), nullable=False) def __init__(self, username): self.username = username
#文章表
class Article(db.Model): __tablename__ = 'aritcle' id = db.Column(db.Integer, primary_key=True,autoincrement=True) title = db.Column(db.String(100), nullable=False) content = db.Column(db.Text, nullable=False) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 正向引用反向引用 author = db.relationship('User', backref=db.backref('articles')) def __init__(self, title, content, author_id): self.title = title self.content = content self.author_id = author_id db.create_all()
author = db.relationship('User', backref=db.backref('articles’))
解释:
*给`Article`这个模型添加一个`author`属性,可以访问这篇文章的作者数据,像访问普通属性一样。
*`backref`是定义反向引用,可以通过`User.article`访问这个模型所写的所有文章
2.多对多
*多对多的关系,要通过一个中间表进行关联
*中间表,不能 ` class ` 的方式实现,只能通过 ` db.Table ` 的方式实现。
*设置关联:` tags = db.relationship(’Tag’, secondary=article_tag, backref=db.backref(‘articles’)) ` 需要使用一个关键字 ` secondary=中间表名 `来进行关联
*访问和数据添加可以通过以下方式进行操作:
1.添加:
article1 = Article(title='bbb') article2 = Article(title='ccc') tag1 = Tag(name='111') tag2 = Tag(name='222') article1.tags.append(tag1) article1.tags.append(tag2) article2.tags.append(tag1) article2.tags.append(tag2) db.session.add(article1) db.session.add(article2) db.session.add(tag1) db.session.add(tag2) db.session.commit()
2.访问
article1 = Article.query.filter(Article.title == 'bbb').first() tags = article1.tags for tag in tags: print tag.name
Flask-Scripte的介绍与安装与使用
1.Flask-Script:Flask-Script的作用是可以通过命令行的形式来操作Flask,例如通过命令跑一个开发版本的服务器,设置数据库,定时任务等。
2.安装:pip install flask-script
3.如果直接在主 ` manage.py ` 中写命令,那么在终端就只需要 ` python manage.py command_name ` 就可以了
4.如果把一些命令集中在一个文件中,那么在终端就需要输入一个父命令,比如 ` python manage.py db init`
5.案例代码
#encoding: utf-8 from flask_script import Manager DBManager= Manager() @DBManager.command def init(): print "数据库初始化" @DBManager.command def migrate(): print "数据库迁移"
#encoding: utf-8 from flask_script import Manager from flask_script_demo import app from db_scripts import DBManager mananger = Manager(app) mananger.add_command('db', DBManager) @mananger.command def runserver(): print '服务器运行成功!' if __name__ == '__main__': mananger.run()
分开 ` models `以及解决循环引用:
1.分开 ` models `的目的是为了让代码更加方便管理
2.如何解决循环引用:把 ` db `放在一个单独的文件中,切断循环引用就可以了。
Flask-Migrate的介绍和使用
1.介绍:因为 ` db.create_all ` 在后期修改字段的时候,不会自动映射到数据库,必须删除表,然后重新运行 ` db.create_all ` 才会重新映射,这样不符合实际需求,因此flask-migrate就是为了解决这个问题,它可以在每次修改的东西映射到数据库中。
2.安装 ` pip install flask-migrate `
3.使用 ` flask_migrate `必须借助 ` flask-scripts `,这个包的 ` MigrateCommand ` 中包含了所有和数据库相关的命令
4. ` flask_migrate ` 相关命令
* ` python manage.py db init `: 初始化一个迁移脚本环境,只需要执行一次
* ` python manage.py db migrate `: 将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令
* ` python manage.py db upgrade `: 将迁移文件真正映射到数据库中,每次运行了 ` migrade `命令后,就要记得运行这个命令
cookie:
1. ` cookie ` 出现的原因:在网站中,http请求是无状态的,也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求的是哪个用户,cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存到本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪一个。
2.如果服务器返回了 ` cookie `给浏览器,那么浏览器下次再请求相同的服务器的时候,就会自动的把 ` cookie ` 发送给浏览器,这个过程,用户根本不需要管。
session:
- ` session ` 介绍:session和cookie的作用有点类似,都是为了存储用户相关信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但服务器已经发展至今,保存一些session信息还是绰绰有余的
- 使用 ` session `的好处:**1.敏感数据不是直接发送给浏览器,而是发送一个` session_id `,服务器将 ` session_id `和敏感数据做一个映射存储在 ` session `(在服务器上面)中,更加安全。**2.` session ` 可以设置过期时间,也从另一个方面,保证了用户的账号安全
flask中的session工作机制
1.介绍:把敏感数据加密后放入` session `中,然后把 ` session `存放到 ` cookie `中,下次请求的时候,再从浏览器发送过来的 ` cookie `中读取 ` session `然后再从` session `中读取敏感数据,并进行解密,获取最终用户数据。
2.flask的这种 ` session `机制,可以节省服务器的开销,因为把所有的信息都存储到了客户端(浏览器)
3.安全是相对的,把 ` session `放到 ` cookie `中,经过加密,也是比较安全的,这点大家可以放心使用。
flask中使用cookie和session
1.cookies:在Flask中操作cookie,是通过response对象来操作,可以在response返回之前,通过response.set_cookie来设置,这个方法有以下几个参数需要注意:
*key:设置cookie的key
*value:key对应的value
*max_age:改cookie的过期时间,如果不设置,则浏览器关闭后就会自动过期
*expires:过期时间,应该是一个datetime类型
*domain:改cookie在哪个域名中有效,一般设置子域名,比如cms.example.com
*path:该cookie在哪个路径下有效
2.session:Flask中的session是通过from flask import session 。然后添加值key和value进去即可,并且,Flask中的session机制是将session信息加密,然后存储在cookie中,专业术语叫做 client side session
操作session
1.session的操作方式:
*使用 ` session `需要从` flask `中导入 ` session `,所有和 ` session `相关的操作都是通过这个变量
*使用 ` session `需要设置 ` SECRET_KEY `,用来作为加密的秘钥。并且这个 ` SECRET_KEY `如果每次服务器启动后都会变化的话,那么之前的 ` session ` 就不能再通过当前这个` SECRET_KEY `进行解密了
*操作 ` session `的时候,跟操作字典是一样的。
*添加 ` session `:` session[‘username'] `。
*删除 ` session.pop(‘username’) ` 或者 ` del session[‘username’] `
*清除所有 ` session `:`session.clear() `
*获取 ` session.get(‘XXX’) `
2.设置session的过期时间
*如果没有指定session的过期时间,那么默认是浏览器关闭后就自动结束
*如果设置了session的permanent属性为True,那么过期时间是31天
*可以通过给 ` app.config ` 设置 ` PERMANENT_SESSION_LIFETIME `来更改过期时间,这个值得数据类型是` datetime.timedelay` 类型
Get请求和post请求
1.get请求
*使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这个时候使用get请求。
*传参:get请求参数是放在url中,并且是通过 ` ? `的形式来指定key和value。
2.post请求
*使用场景:如果要对服务器产生影响,那么使用post请求
*传参:post请求传参不是放在url中,是通过 ` form data `的形式发送给服务器
get和post请求获取参数
1.get请求是通过 ` request.args `来获取
2.post请求是通过 ` request.form `来获取
3.post请求在模板中要注意几点:
*input标签中,要写name来标识这个value和key,方便后台获取
*在写form表单的时候,要指定 ` method=‘POST’ `,并且要指定 ` action=‘/login/ `
4.示例代码
<form action="{{ url_for('login') }}" method="post"> <table> <tbody> <tr> <td>用户名:</td> <td><input type="text" name='username' placeholder="请输入用户名"></td> </tr> <tr> <td>密码:</td> <td><input type="text" name='password' placeholder="请输入密码"></td> </tr> <tr> <td></td> <td><input type="submit" placeholder="登录"></td> </tr> </tbody> </table> </form>
保存全局变量的g属性
g: global
1.g对象是专门用来保存用户的数据的
2.g对象在一次请求中,都是可以使用的
钩子函数(hook):
1.before_request:
*在请求之前执行
*是在视图函数执行之前执行
*这个函数这是一个装饰器,它可以把需要设置为钩子函数的代码放到视图函数执行之前来执行
2.context_processor:
*上下文处理器应该返回一个字典,字典中的 ` key ` 会被模板中当成变量来渲染
*上下文处理器返回字典,在所有页面中都是可用的
*被这个装饰器修饰的钩子函数必须要返回一个字典