初步印象应该是 django大而全、flask小而精、tornado性能高。
底层io处理机制:
tornado、gevent、asyncio、aiohttp:自带异步特性,底层使用的是事件循环+协程,nodejs和go语言都得益于协程轻松实现了高并发。tornado 或 go 开发的应用因为自己实现了高效 http 处理的应用只需要部署自己就可以了
django和flask: 传统的模型,同步框架,阻塞io模型。api写同步代码,使用celery /apscheduler处理异步任务。python 传统的这种 wsgi 模型,主要是为了方便框架开发者只需要专注框架层面,而非 http 处理层面。但这样却增加了服务部署的复杂度,需要同时部署和配置 http server 和 wsgi server ,如果想支持异步还要部署 worker 。
性能:
最基本的 json 的序列化:Django 与 Flask 占优
处理远程 http 请求的能力:Tornado 占绝对优势
数据库与模板处理性能:Tornado 与 Flask 旗鼓相当,Django 饱受诟病的地方就是 Django ORM 确实很慢,Django 的开发效率与维护非常棒,然而 Django ORM 深度绑定了该框架,如果你需要把 Django ORM 换成其它轮子,那么也意味着 Django 的诸多优秀特性将从此告别
结论:
Django:Python 界最全能的 web 开发框架,battery-include 各种功能完备,可维护性和开发速度一级棒。常有人说 Django 慢,其实主要慢在 Django ORM 与数据库的交互上,所以是否选用 Django,取决于项目对数据库交互的要求以及各种优化。而对于 Django 的同步特性导致吞吐量小的问题,其实可以通过 Celery 等解决,倒不是一个根本问题。Django 的项目代表:Instagram,Guardian。
Flask:微框架的典范,号称 Python 代码写得最好的项目之一。Flask 的灵活性,也是双刃剑:能用好 Flask 的,可以做成 Pinterest,用不好就是灾难(显然对任何框架都是这样)。Flask 虽然是微框架,但是也可以做成规模化的 Flask。加上 Flask 可以自由选择自己的数据库交互组件(通常是 Flask-SQLAlchemy),而且加上 celery +redis 等异步特性以后,Flask 的性能相对 Tornado 也不逞多让,也许Flask 的灵活性可能是某些团队更需要的。
Tornado:天生异步,性能强悍是 Tornado 的名片,然而 Tornado 相比 Django 是较为原始的框架,诸多内容需要自己去处理。当然,随着项目越来越大,框架能够提供的功能占比越来越小,更多的内容需要团队自己去实现,而大项目往往需要性能的保证,这时候 Tornado 就是比较好的选择。Tornado项目代表:知乎。
列举代码中的一些区别
Django登录
def login(request):
if request.method == 'GET':
goods = Good.objects.filter(id__gt=1, id__lte=6)
return render(request, 'login.html', {'goods': goods})
elif request.method == 'POST':
# 登录
# 接受客户端发送的数据
username = request.POST.get('username')
password = request.POST.get('password')
# 验证用户名以及密码
users = UserModel.objects.filter(username=username, password=password)
if users.exists():
# 验证成功
res = redirect(reverse('index'))
# coikie
# 1、cookie是储存在客户端
# 2、cookie一般不跨域,不能夸浏览器
# 3、cookie一般是小于4kb的文本
# 4、cookie是有服务器设置的,cookie内容一般和当前用户相关
# res.set_cookie('userid', users.first().id)
# cookie过期时间
# 1、默认过期时间为浏览器会话时间(浏览器关闭会删除)
# 2、expires 设置一个过期时间,datetime
# 3、max_age:设置从当前时间开始进过的秒数
# res.set_cookie('userid', users.first().id, max_age=20)
# d = datetime.datetime(2030, 1, 2)
# res.set_cookie('userid', users.first().id, expires=d)
# session
# 设置session
request.session['userid'] = users.first().id
# 设置session过期时间
request.session.set_expiry(86400)
# 进入首页
# return redirect(reverse('index'))
return res # 相当于上面那句
return render(request, 'login.html')
ps:
dango、flask、tornado一些区别**
django return方式
render(request, ‘login.html’, {‘goods’: goods})只是可以页面渲染,传入数据给模板
redirect(reverse(‘index’)) 只是做页面跳转,不能带数据
HttpResponse(‘ok’) 返回一个ok的页面
return JsonResponse({‘msg’: ‘修改成功’, ‘code’: 1, ‘date’: data, }) 前后端分离返回json数据
flsk return方式
return render_template('index.html', num=num, now=now) 相当于django中render
return redirect(url_for('admin.admin_category')) 相当于django中的redirect 跳转页面
return 'ok' 相当于django中的HttpResponse
tornado return方式
self.write('注册失败')
self.render('register.html', username=usernaem)
self.redirect(self.reverse_url('login'))
# tornado 注册
class RegisterHandler(tornado.web.RequestHandler):
def get(self):
username = self.get_body_argument('username')
# self.render('register.html')
self.render('register.html', username=usernaem)
def post(self):
self.get_body_argument
username = self.get_argument('username')
password = self.get_argument('password')
sex = self.get_argument('sex')
# 检测用户名是否是否已经存在
user = session.query(Person).filter_by(name=username).first()
if user:
self.write('该用户名已注册')
else:
# 注册
person = Person()
person.name = username
person.password = my_md5(password)
person.sex = True if sex == 'man' else False
try:
session.add(person)
session.commit()
except:
session.rollback()
session.flush()
self.write('注册失败')
else:
# 注册成功
# 跳转到登录界面
self.redirect(self.reverse_url('login'))
接受前端返回的数据 (post)
Django 用 username = request.POST.get(‘username’)
flask 用 username = request.form.get(‘username’)
Tornado 用username = self.get_argument(‘username’) # get_body_argument
得到数据库的数据
Django 用
注意用get没找到数据会报错,但是filter没找到不会报错
user = user.objects.get(id=1) # filter、all
flask 用
user = user.query.gey(1) # get 只需要将id填进去即可
user = user.query.filter(User.id==1) # filter 注意2个等号
user = user.query.filter_by(id=1) # filter_by 不需要表名,一个等号
Tornado 用
基本和flask一致,但是其query需要带表名,
user = session.query(Person).filter_by(name=username)
保存至数据库
1、Django
person = Person()
person.name = username
user.save() 保存即可
2、flask 用 这个用db.session
person = Person()
person.name = username
try:
db.session.add(person) # 成功提交
db.session.commit() # 保存
except:
db.session.rollback() # 失败回滚
db.session.flush() # 刷新缓冲区
3、Tornado 这个用session
person = Person()
person.name = username
try:
session.add(person)
session.commit()
except:
session.rollback()
session.flush()
self.write('注册失败')