本文主要是介绍9-tornado-Template优化方法、个人信息案例、tornado中ORM的使用(peewee的使用、peewee_async)、WTForms的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在很多情况下,前端模板中在很多页面有都重复的内容可以使用,比如页头、页尾、甚至中间的内容都有可能重复。这时,为了提高开发效率,我们就可以考虑在共同的部分提取出来,
主要方法有如下:
1. 模板继承
2. UI模板
1 模板继承
common/base.html
{% block content %}
{% end %}
shop2.html
{% extends 'common/base.html'%}{% block content %}
{% end %}
2 UI模板
Tornado中支持累死Vue中的组件功能,就是也公共的内容提取出来当成组件。
具体的使用方式是用tornado.web.UIModule
class Entry(tornado.web.UIModule):def render(self, entry, show_comments=False):return self.render_string("module-entry.html", entry=entry, show_comments=show_comments)settings = {"Entry": Entry,
}
3 个人信息案例
环境搭建
在网站中,少了数据CRUD的操作,但在tornado中,我们知道若想操作的话尽量使用异步的操作,这样效率才会高。
那应该如何编写呢,下面我们来一起做下吧。首先我们先一起搭建下环境。
具体的操作如下:
前端
copy 原生素材
html —> templates
css —> static/css
js —> static/js
img —> static/img
到项目中
后端
from tornado import web, ioloop
from tornado.web import StaticFileHandlerclass IndexHandler(web.RequestHandler):def get(self):self.render('personal.html')import os
base_url = os.path.dirname(os.path.abspath(__file__))
settings={'static_path':os.path.join(base_url,'static'),'static_url_prefix':'/static/','template_path':os.path.join(base_url,'templates')
}
if __name__ == "__main__":app = web.Application([web.URLSpec('/',IndexHandler,name='index'),],debug=True,**settings)app.listen(8000)ioloop.IOLoop.current().start()
MySQL
CREATE TABLE `tornado_demo1`.`t_user` (`id` int(10) NOT NULL,`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`nick_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`passsword` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`phone` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`language` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
熟悉Mysql操作
之前我们了解过pymysql操作数据库,但那是同步的。
我们需要使用一个异步的框架,在这,我们推荐使用aiomysql,它的底层大量的使用了pymysql,只是它通过asyncio实现的访问数据库
安装方式
pip install aiomysql
使用方式
import asyncio
import aiomysqlasync def test_example(loop):pool = await aiomysql.create_pool(host='127.0.0.1', port=3306,user='root', password='root',db='mysql', loop=loop)async with pool.acquire() as conn:async with conn.cursor() as cur:await cur.execute("SELECT 42;")print(cur.description)(r,) = await cur.fetchone()assert r == 42pool.close()await pool.wait_closed()loop = asyncio.get_event_loop()
loop.run_until_complete(test_example(loop))
4 tornado中ORM的使用
4.1 peewee的使用
官网链接
Peewee是一个简单而小型的ORM。使其易于学习且使用直观。
- 一个小的,表达力很强的ORM
- python 2.7+和3.4+(使用3.11开发)
- 支持sqlite,mysql,postgresql和cockroachdb
- 大量的扩展
安装
pip install peewee
tip 需要安装pymysql,不然会报错
peewee.ImproperlyConfigured: MySQL driver not installed!
### 使用方式 #### 创建表from peewee import *db = MySQLDatabase('message', host="127.0.0.1", port=3306, user="root", password="root")class BaseModel(Model):create_time = DateTimeField(default=datetime.now, verbose_name="添加时间")class Music(BaseModel):name = CharField(index=True)singer = CharField(max_length=11, verbose_name="演唱者")duration = CharField(max_length=11, verbose_name="时长")_type = CharField(max_length =11,verbose_name="音乐类型")commany = ForeignKeyField(Commany,verbose_name="版权",backref = "musics")class Meta:database = db table_name = 't_music'class Commany(BaseModel):name = CharField()address = CharField()year - CharField()
db.create_tables([Cmmany,Music])
增加数据
c = Commany()c.name = '中国人'c.full_name = '北京'c.year = 2003c.save()print(c.id)m = Music(name='中国', singer='中国1', duration='1:50',_type='流行', commany=c.id)m.save()
案例数据
commanys = [{'name': '滚石唱片','full_name': '滚石国际音乐股份有限公司','year': 1980},{'name': '华谊兄弟','full_name': '华谊兄弟传媒股份有限公司','year': 1994},{'name': '海蝶音乐','full_name': '北京太合音乐文化发展有限公司','year': 1986},]musics = [{"name": "你是我左边的风景","singer": "林志炫","duration": "2:20","_type": "摇滚","commany": 1},{"name": "把你揉碎捏成苹果","singer": "薛之谦","duration": "2:10","_type": "摇滚","commany": 3},{"name": "游戏人间","singer": "童安格","duration": "1:20","_type": "流行","commany": 2},{"name": "故乡的云","singer": "费翔","duration": "2:40","_type": "摇滚","commany": 1},{"name": "诺言Jason","singer": "青城山下白素贞","duration": "1:10","_type": "古典","commany": 3},{"name": "勇敢的幸福","singer": "Sweety","duration": "1:23","_type": "古典","commany": 2},{"name": "爱丫爱丫","singer": "By2","duration": "2:22","_type": "流行","commany": 1},{"name": "我也曾像你一样","singer": "马天宇","duration": "2:28","_type": "流行","commany": 1}]#### 查询数据The following types of comparisons are supported by peewee:| Comparison | Meaning || ---------- | --------------------------------------- || `==` | x equals y || `<` | x is less than y || `<=` | x is less than or equal to y || `>` | x is greater than y || `>=` | x is greater than or equal to y || `!=` | x is not equal to y || `<<` | x IN y, where y is a list or query || `>>` | x IS y, where y is None/NULL || `%` | x LIKE y where y may contain wildcards || `**` | x ILIKE y where y may contain wildcards || `^` | x XOR y || `~` | Unary negation (e.g., NOT x) |Because I ran out of operators to override, there are some additional query operations available as methods:| Method | Meaning || --------------------- | ----------------------------------------------- || `.in_(value)` | IN lookup (identical to `<<`). || `.not_in(value)` | NOT IN lookup. || `.is_null(is_null)` | IS NULL or IS NOT NULL. Accepts boolean param. || `.contains(substr)` | Wild-card search for substring. || `.startswith(prefix)` | Search for values beginning with `prefix`. || `.endswith(suffix)` | Search for values ending with `suffix`. || `.between(low, high)` | Search for values between `low` and `high`. || `.regexp(exp)` | Regular expression match (case-sensitive). || `.iregexp(exp)` | Regular expression match (case-insensitive). || `.bin_and(value)` | Binary AND. || `.bin_or(value)` | Binary OR. || `.concat(other)` | Concatenate two strings or objects using `||`. || `.distinct()` | Mark column for DISTINCT selection. || `.collate(collation)` | Specify column with the given collation. || `.cast(type)` | Cast the value of the column to the given type. |To combine clauses using logical operators, use:| Operator | Meaning | Example || ---------- | -------------------- | ---------------------------------------------------- || `&` | AND | `(User.is_active == True) & (User.is_admin == True)` || `\|` (pipe) | OR | `(User.is_admin) \| (User.is_superuser)` || `~` | NOT (unary negation) | `~(User.username.contains('admin'))` |Here is how you might use some of these query operators:# Find the user whose username is "charlie".
User.select().where(User.username == 'charlie')# Find the users whose username is in [charlie, huey, mickey]
User.select().where(User.username.in_(['charlie', 'huey', 'mickey']))Employee.select().where(Employee.salary.between(50000, 60000))Employee.select().where(Employee.name.startswith('C'))Blog.select().where(Blog.title.contains(search_string))
更新数据
def update_music():# 方法1:获取数据,在对象上直接修改# m = Music.get_by_id(1)# m.singer='林志炫666'# m.save()# 方法2:利用类方法# update table set ??? where ???Music.update(singer='林志炫').where(Music.id == 1).execute()
删除数据
def delete_music():# 方法1:直接删除对象# m = Music.get_by_id(8)# m.delete_instance()# 方法2:利用类方法Music.delete().where(Music.id >5).execute()
4.2 peewee_async
peewee_async
安装
PostgreSQL
pip install --pre peewee-async
pip install aiopg
MySQL
pip install --pre peewee-async
pip install aiomysql
案例
import asyncio
import peewee
import peewee_async# Nothing special, just define model and database:database = peewee_async.PostgresqlDatabase(database='db_name',user='user',host='127.0.0.1',port='5432',password='password'
)class TestModel(peewee.Model):text = peewee.CharField()class Meta:database = database# Look, sync code is working!TestModel.create_table(True)
TestModel.create(text="Yo, I can do it sync!")
database.close()# Create async models manager:objects = peewee_async.Manager(database)# No need for sync anymore!database.set_allow_sync(False)async def handler():await objects.create(TestModel, text="Not bad. Watch this, I'm async!")all_objects = await objects.execute(TestModel.select())for obj in all_objects:print(obj.text)loop = asyncio.get_event_loop()
loop.run_until_complete(handler())
loop.close()# Clean up, can do it sync again:
with objects.allow_sync():TestModel.drop_table(True)# Expected output:
# Yo, I can do it sync!
# Not bad. Watch this, I'm async!
5 WTForms的使用
简介
WTForms是用于Python Web开发的灵活的表单验证和呈现库。它可以与您选择的任何Web框架和模板引擎一起使用。
WTForms文档
WTForms_Tornado
安装
pip install wtforms-tornado
案例
import tornado.ioloop
import tornado.webfrom wtforms.fields import IntegerField
from wtforms.validators import Required
from wtforms_tornado import Formclass SumForm(Form):a = IntegerField(validators=[Required()])b = IntegerField(validators=[Required()])class SumHandler(tornado.web.RequestHandler):def get(self):self.write("Hello, world")def post(self):form = SumForm(self.request.arguments)if form.validate():self.write(str(form.data['a'] + form.data['b']))else:self.set_status(400)self.write("" % form.errors)application = tornado.web.Application([(r"/", SumHandler),
])if __name__ == "__main__":application.listen(8888)tornado.ioloop.IOLoop.instance().start()
表单验证
wftform.py
from wtforms.fields import IntegerField,StringField
from wtforms_tornado import Form
from wtforms.validators import DataRequired, Lengthclass UserForm(Form):id = IntegerField('ID')username = StringField('用户名',validators=[DataRequired(message='请输入用户名'),Length(min=3,max=8,message='请输入3-8长度的用户名')])nick_name = StringField('昵称')email = StringField('Email')password = StringField('密码')phone = StringField('手机号')language = StringField('语言')
handler.py
forms = UserForm(self.request.arguments)
if forms.validate():del forms.data['id']await objs.create(User,**forms.data)self.render('personal26.html',user_form = forms)
else:self.render('personal26.html',user_form = forms)
HTML生成
{% autoescape None %}{% for field in user_form %}{% if field.label.text == "ID"%}<div class="form-group">{{ field(class_="au-input au-input--full",placeholder=field.label.text)}}</div>{% else %}<div class="form-group">{{ field.label }}{{ field(class_="au-input au-input--full",placeholder=field.label.text)}}{% if field.errors %}{{field.errors}}{% end %}</div>{% end %}
{% end %}
这篇关于9-tornado-Template优化方法、个人信息案例、tornado中ORM的使用(peewee的使用、peewee_async)、WTForms的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!