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的使用
在很多情况下,前端模板中在很多页面有都重复的内容可以使用,比如页头、页尾、甚至中间的内容都有可能重复。这时,为了提高开发效率,我们就可以考虑在共同的部分提取出来, 主要方法有如下: 1. 模板继承 2. U…...
IDEA中.java .class .jar的含义与联系
当使用IntelliJ IDEA这样的集成开发环境进行Java编程时,通常涉及.java源代码文件、.class编译后的字节码文件以及.jar可执行的Java存档文件。 1. .java 文件: 1.这些文件包含了Java源代码,以文本形式编写。它们通常位于项目中的源代码目录中…...
北斗三号短报文森林消防应急通信及天通野外图传综合方案
森林火灾突发性强、破坏性大、危险性高,是全球发生最频繁、处置最困难、危害最严重的自然灾害之一,是生态文明建设成果和森林资源安全的最大威胁,甚至可能引发生态灾难和社会危机。我国总体上是一个缺林少绿、生态脆弱的国家,是一…...
js Array.every()的使用
2023.12.13今天我学习了如何使用Array.every()的使用,这个方法是用于检测数组中所有存在的元素。 比如我们需要判断这个数组里面的全部元素是否都包含张三,可以这样写: let demo [{id: 1, name: 张三}, {id: 2, name: 张三五}, {id: 3, name…...
前端编码中快速填充内容--乱数假文
写前端页面的时候,如果要快速插入图片,可以使用 https://picsum.photos/ 详见笔者这篇博文: 工具网站:随机生成图片的网站-CSDN博客 可是,如果要快速填充文字内容该怎么做呢? 以前,我们都是…...
数据结构二维数组计算题,以行为主?以列为主?
1.假设以行序为主序存储二维数组Aarray[1..100,1..100],设每个数据元素占2个存储单元,基地址为10,则LOC[5,5]( )。 A.808 B.818 C.1010 D&…...
springboot(ssm电影院订票信息管理系统 影院购票系统Java系统
springboot(ssm电影院订票信息管理系统 影院购票系统Java系统 开发语言:Java 框架:ssm/springboot vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或8.0࿰…...
AI 问答-供应链管理-相关概念:SCM、SRM、MDM、DMS、ERP、OBS、CRM、WMS...
一、供应链管理是什么 供应链管理:理解供应链管理_snowli的博客-CSDN博客 二、SCM 供应链管理 SCM全称为“Supply Chain Management”,即供应链管理。 SCM是企业管理范畴中一个非常重要的概念,指的是企业与供应商、生产商、分销商等各方之…...
初学vue3与ts:vue3选项式api获取当前路由地址
vue2的获取方法 this.$route.pathvue3选项式api获取方法 import { useRouter } from vue-router; const router useRouter(); console.log(router) console.log(router.currentRoute.value.path)...
2023最新大模型实验室解决方案
人工智能是引领未来的新兴战略性技术,是驱动新一轮科技革命和产业变革的重要力量。近年来,人工智能相关技术持续演进,产业化和商业化进程不断提速,正在加快与千行百业深度融合。 大模型实验室架构图 大模型实验室建设内容 一、课…...
leetcode707.设计链表
题目描述 你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向链表,则还需要属性 prev 以指示链表中的…...
【K8s】Kubernetes CRD 介绍(控制器)
文章目录 CRD 概述1. 操作CRD1.1 创建 CRD1.2 操作 CRD 2. 其他笔记2.1 Kubectl 发现机制2.2 校验 CR2.3 简称和属性 3. 架构设计3.1 控制器概览 参考 CRD 概述 CR(Custom Resource)其实就是在 Kubernetes 中定义一个自己的资源类型,是一个具…...
Python 小程序之PDF文档加解密
PDF文档的加密和解密 文章目录 PDF文档的加密和解密前言一、总体构思二、使用到的库三、PDF文档的加密1.用户输入模块2.打开并读取文档数据3.遍历保存数据到新文档4.新文档进行加密5.新文档命名生成路径6.保存新加密的文档 四、PDF文档的解密1.用户输入模块2.前提准备2.文件解密…...
使用python脚本一个简单的搭建ansible集群
1.环境说明: 角色主机名ip地址控制主机server192.168.174.150受控主机/被管节点client1192.168.174.151受控主机/被管节点client2192.168.174.152 2.安装python和pip包 yum install -y epel-release yum install -y python python-pip 3.pip安装依赖库 pip in…...
【价值几十万的仿抖音直播电商系统源码共享】
当下,传统的图文电商模式已经走向没落,以抖音为首的直播电商模式备受用户追捧,它具有实时直播和强互动的特点,是传统电商所不具备的优势。而且,当前正是直播电商的红利期,很多主播和品牌商都通过直播电商业…...
对于vue3项目中使用shareReward还是shareReward.value的问题
问: // 设置当前有没有分享过 默认是false const shareReward ref(false) // 是否是第一次分享 来判断是否发放抽奖次数 function haveShare() { console.log(进入haveshare) if (userInfo.uid && shareReward.value) { rewardTimes(2).then((res) &…...
利用websockify将websocket通信转换成tcp
文章目录 前言websockifywebsockify 介绍websockify 使用 探索的过程提供基础TCP服务测试可用 实现Websocket客户端开始测试websockify功能再次启动websockify单独实现一个js版本websocket客户端 什么是VNC总结 前言 目前遇到一个问题,原本的服务都是利用tcp通信的…...
【LeetCode刷题】-- 163.缺失的区间
163.缺失的区间 class Solution {public List<List<Integer>> findMissingRanges(int[] nums, int lower, int upper) {List<List<Integer>> res new ArrayList<>();for(int num : nums){if(lower < num){res.add(Arrays.asList(lower,num -…...
ClickHouse为何如此之快
针对ClickHouse为什么很快的问题,基于对ClickHouse的基础概念之上,一般会回答是因为是列式存储数据库,同时也会说是使用了向量化引擎,所以快。上面两方面的解释也都能够站得住脚,但是依然不能够解释真正核心的原因。因…...
Avalonia中如何将View事件映射到ViewModel层
前言 前面的文章里面我们有介绍在Wpf中如何在View层将事件映射到ViewModel层的文章,传送门,既然WPF和Avalonia是两套不同的前端框架,那么WPF里面实现模式肯定在这边就用不了,本篇我们将分享一下如何在Avalonia前端框架下面将事件映射到ViewModel层。本章内容还是在上一节的…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果