赞
踩
在很多情况下,前端模板中在很多页面有都重复的内容可以使用,比如页头、页尾、甚至中间的内容都有可能重复。
这时,为了提高开发效率,我们就可以考虑在共同的部分提取出来,
主要方法有如下:
1. 模板继承
2. UI模板
common/base.html
{% block content %}
{% end %}
shop2.html
{% extends 'common/base.html'%}
{% block content %}
{% end %}
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,
}
环境搭建
在网站中,少了数据CRUD的操作,但在tornado中,我们知道若想操作的话尽量使用异步的操作,这样效率才会高。
那应该如何编写呢,下面我们来一起做下吧。首先我们先一起搭建下环境。
具体的操作如下:
前端
copy 原生素材
html —> templates
css —> static/css
js —> static/js
img —> static/img
到项目中
后端
from tornado import web, ioloop from tornado.web import StaticFileHandler class 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 aiomysql async 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 == 42 pool.close() await pool.wait_closed() loop = asyncio.get_event_loop() loop.run_until_complete(test_example(loop))
Peewee是一个简单而小型的ORM。使其易于学习且使用直观。
安装
pip install peewee
tip 需要安装pymysql,不然会报错
- 1
- 2
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 = 2003
c.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()
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!
简介
WTForms是用于Python Web开发的灵活的表单验证和呈现库。它可以与您选择的任何Web框架和模板引擎一起使用。
WTForms文档
WTForms_Tornado
安装
pip install wtforms-tornado
案例
import tornado.ioloop import tornado.web from wtforms.fields import IntegerField from wtforms.validators import Required from wtforms_tornado import Form class 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, Length
class 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)
{% 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 %}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。