Skip to content

Commit 2e7e359

Browse files
committed
docs: 更新了古诗词插件文档
1 parent 27bc4bb commit 2e7e359

1 file changed

Lines changed: 174 additions & 98 deletions

File tree

app/plugins/poem/README.md

Lines changed: 174 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
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 // 应用开发目录
@@ -17,8 +30,7 @@
1730
```
1831

1932
## 定义路由
20-
21-
首先我们在控制层文件`controller.py`中定义一个红图,并且定义两个视图函数
33+
首先,在控制层文件`controller.py`下定义一个红图`redprint`,以及业务相关的视图函数。
2234

2335
```python
2436
from flask import jsonify
@@ -27,46 +39,63 @@ from lin.redprint import Redprint
2739
from app.plugins.poem.app.forms import PoemSearchForm
2840
from .model import Poem
2941

30-
api = Redprint('demo')
42+
api = Redprint('poem')
3143

3244

3345
@api.route('/all', methods=['GET'])
3446
def 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
5164
from lin.interface import InfoCrud as Base
52-
from sqlalchemy import Column, String, Integer
65+
from sqlalchemy import Column, String, Integer, Text
5366

5467

5568
class 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
7099
from lin.forms import Form
71100
from wtforms import StringField
72101
from 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
87127
from .controller import api
88128
from .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

98140
PLUGIN_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
108150
from 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

Comments
 (0)