1- # 插件 demo(古诗展示插件:poem)
1+ ---
2+ title : 开发一个小插件
3+ ---
24
3- > 在大家已经了解了插件机制后,我们按照插件开发规范开发了一个古诗展示插件,在这个 demo 中,你会学习到一个简单插件的整个开发流程和注意事项
5+ # < H2Icon /> 开发一个小插件(目前处于测试状态)
46
5- ### 插件目录结构
7+ Lin 的插件很灵活,你可以在本地的 plugins 目录下使用一个插件,或者通过 ` pip ` 安装一个插件到 site-packages 中。
68
9+
10+ > 在大家已经了解了插件机制和插件的使用方法后,本小结我们来手把手带着大家来开发一个简易的古诗词插件,我们选择在本地的` app/plugins ` 目录下进行开发,你将学到一个插件的整个开发流程和注意事项。好了,话不多说,我们开始吧!
11+
12+ ::: tip
13+ 定义只涉及前端的插件为` A型插件 ` ,只涉及后端的插件为` B型插件 ` ,需要前后端对接 API 共同完成一个业务逻辑的插件为` AB型插件 ` 。本插件为前后端共同协作的` AB型插件 ` ,所以为了规范统一,请特别注意你们的插件命名一致哦。
14+ :::
15+
16+ ## 插件目录结构
17+ 在开发前,我们首先来浏览一下插件的目录结构。
18+ 在` app/plugins ` 目录下创建以插件名称命名的目录,我们所开发的示例插件为古诗词展示插件,所以以` poem ` 来命名。我们在` app/plugins/poem/app ` 目录下进行插件的开发,其余文件含义请查看下面的注释。
719``` bash
820├───poem
921│ │ config.py // 配置文件(必需),记录关于插件的可用配置
22+ │ │ info.py // 插件基本信息
1023│ │ README.md // 插件文档
1124│ │
1225│ └───app // 应用开发目录
1730```
1831
1932## 定义路由
20-
21- 首先我们在控制层文件` controller.py ` 中定义一个红图,并且定义两个视图函数
33+ 首先,在控制层文件` controller.py ` 下定义一个红图` redprint ` ,以及业务相关的视图函数。
2234
2335``` python
2436from flask import jsonify
@@ -27,46 +39,63 @@ from lin.redprint import Redprint
2739from app.plugins.poem.app.forms import PoemSearchForm
2840from .model import Poem
2941
30- api = Redprint(' demo ' )
42+ api = Redprint(' poem ' )
3143
3244
3345@api.route (' /all' , methods = [' GET' ])
3446def get_list ():
3547 poems = Poem().get_all()
3648 return jsonify(poems)
3749
38-
39- @api.route (' /search' , methods = [' GET' ])
40- def search ():
41- form = PoemSearchForm().validate_for_api() # 调用数据校验层校验类校验用户传递过来的参数
42- poems = Poem().search(form.q.data)
43- return jsonify(poems)
50+ ...
4451```
4552
53+ ::: warning
54+ 由于本插件只有一个控制器,也就是只有一个` redprint ` ,那么Lin内核所生成的路由不会有二级前缀,只有一个一级前缀,即/plugin,对此如果你还不够了解,请移步阅读[ 插件中的路由规范] ( ./plugin_practice.md#上传图片到本地 )
55+ :::
56+
4657## 定义数据库模型类
58+ 由于poem插件所实现的业务需要依托数据库,所以我们下面需要在模型层文件设计一个名为Poem的模型类,这里请先检查你的数据库中是否已存在同名表再确认命名。
4759
48- ` poem ` 插件的实现的业务需要依托数据库,所以我们下面需要在模型层文件设计一个名为` Poem ` 的模型类
4960
5061``` python
62+ from lin.core import lin_config
63+ from lin.exception import NotFound
5164from lin.interface import InfoCrud as Base
52- from sqlalchemy import Column, String, Integer
65+ from sqlalchemy import Column, String, Integer, Text
5366
5467
5568class Poem (Base ):
5669 id = Column(Integer, primary_key = True , autoincrement = True )
5770 title = Column(String(50 ), nullable = False , comment = ' 标题' )
5871 author = Column(String(50 ), default = ' 未名' , comment = ' 作者' )
59- dynasty = Column(String(50 ), default = ' 位置' , comment = ' 朝代' )
60- content = Column(String(255 ), nullable = False , comment = ' 内容' )
72+ dynasty = Column(String(50 ), default = ' 未知' , comment = ' 朝代' )
73+ content = Column(Text, nullable = False , comment = ' 内容' )
74+ image = Column(String(255 ), default = ' ' , comment = ' 配图' )
75+
76+ def get_all (self ):
77+ poems = self .query.filter_by(delete_time = None ).limit(
78+ lin_config.get_config(' poem.limit' )
79+ ).all()
80+ if not poems:
81+ raise NotFound(msg = ' 没有找到相关诗词' )
82+ return poems
83+ ```
84+ 同样的,本插件只需要一个模型类,如果你所设计的插件需要多个模型类,请定义多个模型层文件。如果你对模型类的开发还不够了解,可以先去学习一下[ 模型管理] ( './authority_and_models.md' ) 小节
6185
62- ...
86+ ## 关于配置文件
87+ 在上面的模型层代码中,你或许已经发现,我们从lin的核心库中导入了` lin_config ` ,并且使用` lin_config.get_config('poem.limit') ` 获取到了配置,那么配置文件定义在哪里呢?
88+ 在插件目录结构中,我们可以发现` config.py ` 文件的位置。我们打开` config.py ` 配置文件,可以发现,Lin建议用户定义的配置项是小写的。如果你开发的插件有更多的配置,都可以在这个文件中添加。
89+ ``` python
90+ # app/plugins/poem/config.py
91+ limit = 20
6392```
6493
6594## 定义数据校验类
66-
6795当我们需要校验用户传递过来的参数时,别忘了数据校验层的存在,我们在` forms.py ` 中定义一个简单的数据校验类` PoemSearchForm ` 。并在视图函数中调用。
6896
6997``` python
98+ # app/plugins/poem/app/forms.py
7099from lin.forms import Form
71100from wtforms import StringField
72101from wtforms.validators import DataRequired
@@ -77,17 +106,30 @@ class PoemSearchForm(Form):
77106 DataRequired(message = ' 必须传入搜索关键字' )
78107 ])
79108
109+
110+ # app/plugins/poem/app/controller.py
111+ ...
112+
113+ @api.route (' /search' , methods = [' GET' ])
114+ def search ():
115+ form = PoemSearchForm().validate_for_api()
116+ poems = Poem().search(form.q.data)
117+ return jsonify(poems)
118+
80119```
81120
82121## 导出文件
83122
84- 基本业务逻辑已经实现,最关键的一步还要导出文件,也就是在` poem/app/__init__.py ` 中写入要被 Lin 的加载器自动加载的红图 api 和数据模型类
123+ 基本业务逻辑已经实现,最关键的一步还要导出文件,也就是在` poem/app/__init__.py ` 中写入要被 Lin 的 ` loader ` (加载器)自动加载的 ` 红图 api` 和 ` 数据模 ` 型类
85124
86125``` python
126+ # app/plugins/poem/app/__init__.py
87127from .controller import api
88128from .model import Poem
89129```
90130
131+ 如果你有多个红图或者多个模型类,同样在这个文件下导入即可,但请注意` 不要重名 ` 。
132+
91133## 用配置开启插件
92134
93135> 最后,在` app/config/setting.py ` 中添加如下配置:
@@ -96,13 +138,13 @@ from .model import Poem
96138# setting.py
97139
98140PLUGIN_PATH = {
99- ' poem' : {' path' : ' app.plugins.poem' , ' enable' : True },
141+ ' poem' : {' path' : ' app.plugins.poem' , ' enable' : True , ' limit ' : 5 },
100142}
101143```
102144
103- 对于该配置项的含义,已经在[ 插件使用] 一小节详细介绍。
145+ 对于该配置项的含义,已经在[ 插件使用] ( ./plugin_practice.md ) 一小节详细介绍。此处设置了limit为5,他的权级会高于上述 ` config.py ` 中的权级,所以在调用配置时,会优先调用 ` setting.py ` 中的配置 。
104146
105- 至此,这个简单插件的开发已经完成了。运行项目,我们会发现收据库中会出现我们所创建的 poem 表。下面请打开 fake .py,替换成下面的代码并执行,向表中添加一些初始数据 。
147+ 至此,这个简单插件的全部开发已经完成了。运行starter.py,我们会发现数据库中会出现我们想要创建的 ` poem ` 表。下面请打开项目根目录下的fake .py,替换成下面的代码并执行,向该表中添加一些初始数据 。
106148
107149``` python
108150from app.app import create_app
@@ -114,98 +156,132 @@ with app.app_context():
114156 with db.auto_commit():
115157 # 添加诗歌
116158 poem1 = Poem()
117- poem1.title = ' 夜宿山寺'
118- poem1.author = ' 李白'
119- poem1.dynasty = ' 唐代'
120- poem1.content = ' 危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。'
159+ poem1.title = ' 生查子·元夕'
160+ poem1.author = ' 欧阳修'
161+ poem1.dynasty = ' 宋代'
162+ poem1.content = """ 去年元夜时,花市灯如昼。
163+ 月上柳梢头,人约黄昏后。
164+ 今年元夜时,月与灯依旧。
165+ 不见去年人,泪湿春衫袖。"""
121166 db.session.add(poem1)
122167
123168 poem2 = Poem()
124- poem2.title = ' 视刀环歌'
125- poem2.author = ' 刘禹锡'
126- poem2.dynasty = ' 唐代'
127- poem2.content = ' 常恨言语浅,不如人意深。今朝两相视,脉脉万重心。'
169+ poem2.title = ' 临江仙·送钱穆父'
170+ poem2.author = ' 苏轼'
171+ poem2.dynasty = ' 宋代'
172+ poem2.content = """ 一别都门三改火,天涯踏尽红尘。依然一笑作春温。无波真古井,有节是秋筠。
173+ 惆怅孤帆连夜发,送行淡月微云。尊前不用翠眉颦。人生如逆旅,我亦是行人。"""
128174 db.session.add(poem2)
129175
130176 poem3 = Poem()
131- poem3.title = ' 己亥杂诗 · 其五'
132- poem3.author = ' 龚自珍'
133- poem3.dynasty = ' 清代'
134- poem3.content = ' 浩荡离愁白日斜,吟鞭东指即天涯。落红不是无情物,化作春泥更护花。'
177+ poem3.title = ' 春望词四首'
178+ poem3.author = ' 薛涛'
179+ poem3.dynasty = ' 唐代'
180+ poem3.content = """ 花开不同赏,花落不同悲。
181+ 欲问相思处,花开花落时。
182+ 揽草结同心,将以遗知音。
183+ 春愁正断绝,春鸟复哀吟。
184+ 风花日将老,佳期犹渺渺。
185+ 不结同心人,空结同心草。
186+ 那堪花满枝,翻作两相思。
187+ 玉箸垂朝镜,春风知不知。"""
135188 db.session.add(poem3)
136189
137190 poem4 = Poem()
138- poem4.title = ' 杨柳枝'
139- poem4.author = ' 温庭筠'
140- poem4.dynasty = ' 唐代'
141- poem4.content = ' 井底点灯深烛伊,共郎长行莫围棋。玲珑骰子安红豆,入骨相思知不知。'
191+ poem4.title = ' 长相思'
192+ poem4.author = ' 纳兰性德'
193+ poem4.dynasty = ' 清代'
194+ poem4.content = """ 山一程,水一程,身向榆关那畔行,夜深千帐灯。
195+ 风一更,雪一更,聒碎乡心梦不成,故园无此声。"""
142196 db.session.add(poem4)
143- ```
144-
145- ## 用 postman 调试接口
146-
147- ### 获取所有诗词
148-
149- URL
150197
151- > GET http://localhost:5000/plugin/poem/demo/all
198+ poem5 = Poem()
199+ poem5.title = ' 离思五首·其四'
200+ poem5.author = ' 元稹'
201+ poem5.dynasty = ' 唐代'
202+ poem5.content = """ 曾经沧海难为水,除却巫山不是云。
203+ 取次花丛懒回顾,半缘修道半缘君。"""
204+ db.session.add(poem5)
205+
206+ poem6 = Poem()
207+ poem6.title = ' 浣溪沙·一曲新词酒一杯'
208+ poem6.author = ' 晏殊'
209+ poem6.dynasty = ' 宋代'
210+ poem6.content = """ 一曲新词酒一杯,去年天气旧亭台。夕阳西下几时回?
211+ 无可奈何花落去,似曾相识燕归来。小园香径独徘徊。"""
212+ db.session.add(poem6)
213+
214+ poem7 = Poem()
215+ poem7.title = ' 浣溪沙·残雪凝辉冷画屏'
216+ poem7.author = ' 纳兰性德'
217+ poem7.dynasty = ' 清代'
218+ poem7.content = """ 残雪凝辉冷画屏,落梅横笛已三更,更无人处月胧明。
219+ 我是人间惆怅客,知君何事泪纵横,断肠声里忆平生。 """
220+ db.session.add(poem7)
221+
222+ poem8 = Poem()
223+ poem8.title = ' 蝶恋花·春景'
224+ poem8.author = ' 苏轼'
225+ poem8.dynasty = ' 宋代'
226+ poem8.content = """ 花褪残红青杏小。燕子飞时,绿水人家绕。枝上柳绵吹又少。天涯何处无芳草。
227+ 墙里秋千墙外道。墙外行人,墙里佳人笑。笑渐不闻声渐悄。多情却被无情恼。"""
228+ db.session.add(poem8)
229+ ```
152230
153- Response 200:
231+ ## 用poseman调试接口
154232
233+ ### 调用获取所有诗词接口
234+ 使用GET方法访问` http://localhost:5000/plugin/poem/demo/all ` url,将会得到如下数据:
155235``` json
156236[
157- {
158- "author" : " 李白" ,
159- "content" : " 危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。" ,
160- "create_time" : 1548422493000 ,
161- "dynasty" : " 唐代" ,
162- "id" : 1 ,
163- "title" : " 夜宿山寺"
164- },
165- {
166- "author" : " 刘禹锡" ,
167- "content" : " 常恨言语浅,不如人意深。今朝两相视,脉脉万重心。" ,
168- "create_time" : 1548422493000 ,
169- "dynasty" : " 唐代" ,
170- "id" : 2 ,
171- "title" : " 视刀环歌"
172- },
173- {
174- "author" : " 龚自珍" ,
175- "content" : " 浩荡离愁白日斜,吟鞭东指即天涯。落红不是无情物,化作春泥更护花。" ,
176- "create_time" : 1548422493000 ,
177- "dynasty" : " 清代" ,
178- "id" : 3 ,
179- "title" : " 己亥杂诗 · 其五"
180- },
181- {
182- "author" : " 温庭筠" ,
183- "content" : " 井底点灯深烛伊,共郎长行莫围棋。玲珑骰子安红豆,入骨相思知不知。" ,
184- "create_time" : 1548422493000 ,
185- "dynasty" : " 唐代" ,
186- "id" : 4 ,
187- "title" : " 杨柳枝"
188- }
237+ {
238+ "author" : " 欧阳修" ,
239+ "content" : " 去年元夜时,花市灯如昼。\n 月上柳梢头,人约黄昏后。\n 今年元夜时,月与灯依旧。\n 不见去年人,泪湿春衫袖。" ,
240+ "create_time" : 1548581209000 ,
241+ "dynasty" : " 宋代" ,
242+ "id" : 1 ,
243+ "image" : " " ,
244+ "title" : " 生查子·元夕"
245+ },
246+ {
247+ "author" : " 苏轼" ,
248+ "content" : " 一别都门三改火,天涯踏尽红尘。依然一笑作春温。无波真古井,有节是秋筠。\n 惆怅孤帆连夜发,送行淡月微云。尊前不用翠眉颦。人生如逆旅,我亦是行人。" ,
249+ "create_time" : 1548581209000 ,
250+ "dynasty" : " 宋代" ,
251+ "id" : 2 ,
252+ "image" : " " ,
253+ "title" : " 临江仙·送钱穆父"
254+ },
255+ {
256+ "author" : " 薛涛" ,
257+ "content" : " 花开不同赏,花落不同悲。\n 欲问相思处,花开花落时。\n 揽草结同心,将以遗知音。\n 春愁正断绝,春鸟复哀吟。\n 风花日将老,佳期犹渺渺。\n 不结同心人,空结同心草。\n 那堪花满枝,翻作两相思。\n 玉箸垂朝镜,春风知不知。" ,
258+ "create_time" : 1548581209000 ,
259+ "dynasty" : " 唐代" ,
260+ "id" : 3 ,
261+ "image" : " " ,
262+ "title" : " 春望词四首"
263+ },
264+ {
265+ "author" : " 纳兰性德" ,
266+ "content" : " 山一程,水一程,身向榆关那畔行,夜深千帐灯。\n 风一更,雪一更,聒碎乡心梦不成,故园无此声。" ,
267+ "create_time" : 1548581209000 ,
268+ "dynasty" : " 清代" ,
269+ "id" : 4 ,
270+ "image" : " " ,
271+ "title" : " 长相思"
272+ },
273+ {
274+ "author" : " 元稹" ,
275+ "content" : " 曾经沧海难为水,除却巫山不是云。\n 取次花丛懒回顾,半缘修道半缘君。" ,
276+ "create_time" : 1548581209000 ,
277+ "dynasty" : " 唐代" ,
278+ "id" : 5 ,
279+ "image" : " " ,
280+ "title" : " 离思五首·其四"
281+ }
189282]
190283```
191284
192- ### 按标题搜索诗词
193-
194- URL
195-
196- > GET http://localhost:5000/plugin/poem/demo/search?q= <string >
197-
198- Response 200:
285+ ## 小结
199286
200- ``` json
201- [
202- {
203- "author" : " 龚自珍" ,
204- "content" : " 浩荡离愁白日斜,吟鞭东指即天涯。落红不是无情物,化作春泥更护花。" ,
205- "create_time" : 1548422493000 ,
206- "dynasty" : " 清代" ,
207- "id" : 3 ,
208- "title" : " 己亥杂诗 · 其五"
209- }
210- ]
211- ```
287+ 在本节中,我们遵守插件的开发规范,很容易地开发出了古诗词插件的后端API部分,如果你想了解前端插件部分的实际开发,请移步[ 前端插件] ( #../client/plugin.md ) 。
0 commit comments