吴江设计网站公司,2024免费网站推广大全,庆阳网约车,2一3万元小型加工设备在很多情况下#xff0c;前端模板中在很多页面有都重复的内容可以使用#xff0c;比如页头、页尾、甚至中间的内容都有可能重复。这时#xff0c;为了提高开发效率#xff0c;我们就可以考虑在共同的部分提取出来#xff0c;
主要方法有如下#xff1a;
1. 模板继承
2. U…在很多情况下前端模板中在很多页面有都重复的内容可以使用比如页头、页尾、甚至中间的内容都有可能重复。这时为了提高开发效率我们就可以考虑在共同的部分提取出来
主要方法有如下
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_commentsFalse):return self.render_string(module-entry.html, entryentry, show_commentsshow_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,nameindex),],debugTrue,**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(host127.0.0.1, port3306,userroot, passwordroot,dbmysql, looploop)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。使其易于学习且使用直观。
一个小的表达力很强的ORMpython 2.7和3.4使用3.11开发支持sqlitemysqlpostgresql和cockroachdb大量的扩展
安装
pip install peeweetip
需要安装pymysql,不然会报错peewee.ImproperlyConfigured: MySQL driver not installed!
### 使用方式 #### 创建表from peewee import *db MySQLDatabase(message, host127.0.0.1, port3306, userroot, passwordroot)class BaseModel(Model):create_time DateTimeField(defaultdatetime.now, verbose_name添加时间)class Music(BaseModel):name CharField(indexTrue)singer CharField(max_length11, verbose_name演唱者)duration CharField(max_length11, verbose_name时长)_type CharField(max_length 11,verbose_name音乐类型)commany ForeignKeyField(Commany,verbose_name版权,backref musics)class Meta:database db table_name t_musicclass 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, duration1:50,_type流行, commanyc.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 aiopgMySQL
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(databasedb_name,useruser,host127.0.0.1,port5432,passwordpassword
)class TestModel(peewee.Model):text peewee.CharField()class Meta:database database# Look, sync code is working!TestModel.create_table(True)
TestModel.create(textYo, 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, textNot bad. Watch this, Im 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, Im 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(min3,max8,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 classform-group{{ field(class_au-input au-input--full,placeholderfield.label.text)}}/div{% else %}div classform-group{{ field.label }}{{ field(class_au-input au-input--full,placeholderfield.label.text)}}{% if field.errors %}{{field.errors}}{% end %}/div{% end %}
{% end %}