Skip to content

Commit 0e65553

Browse files
committed
refactor:admin pydantic validator
1 parent d227e2f commit 0e65553

14 files changed

Lines changed: 432 additions & 213 deletions

File tree

app/api/cms/admin.py

Lines changed: 161 additions & 120 deletions
Large diffs are not rendered by default.

app/api/cms/file.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@
33
:license: MIT, see LICENSE for more details.
44
"""
55
from flask import Blueprint, request
6-
76
from lin import login_required
7+
8+
from app.api import AuthorizationBearerSecurity, api
89
from app.extension.file.local_uploader import LocalUploader
910

1011
file_api = Blueprint("file", __name__)
1112

1213

1314
@file_api.route("", methods=["POST"])
1415
@login_required
16+
@api.validate(
17+
tags=["文件"],
18+
security=[AuthorizationBearerSecurity],
19+
)
1520
def post_file():
21+
"""
22+
上传文件
23+
"""
1624
files = request.files
1725
uploader = LocalUploader(files)
1826
ret = uploader.upload()

app/api/cms/log.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import math
22

33
from flask import Blueprint, g
4+
from lin import DocResponse, Log, db, group_required, permission_meta
45
from sqlalchemy import text
56

67
from app.api import AuthorizationBearerSecurity, api
7-
from app.api.cms.schema import LogPageSchema, LogQuerySearchSchema, UsernameListSchema
8-
from lin import DocResponse, Log, db, group_required, permission_meta
8+
from app.api.cms.schema.log import (
9+
LogPageSchema,
10+
LogQuerySearchSchema,
11+
UsernameListSchema,
12+
)
913

1014
log_api = Blueprint("log", __name__)
1115

app/api/cms/model/user.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
from sqlalchemy import func
2-
31
from lin import User as LinUser
42
from lin import db, manager
3+
from sqlalchemy import func
54

65

76
class User(LinUser):

app/api/cms/schema/__init__.py

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +0,0 @@
1-
import re
2-
from datetime import datetime
3-
from typing import List, Optional
4-
5-
from flask import g
6-
from pydantic import Field, validator
7-
8-
from lin import BaseModel
9-
from app.schema import BasePageSchema, datetime_regex
10-
11-
12-
class UsernameListSchema(BaseModel):
13-
items: List[str]
14-
15-
16-
class LogQuerySearchSchema(BaseModel):
17-
keyword: Optional[str] = None
18-
name: Optional[str] = None
19-
start: Optional[str] = Field(None, description="YY-MM-DD HH:MM:SS")
20-
end: Optional[str] = Field(None, description="YY-MM-DD HH:MM:SS")
21-
count: int = Field(5, gt=0, lt=16, description="0 < count < 16")
22-
page: int = 0
23-
24-
@validator("start", "end")
25-
def datetime_match(cls, v, values, **kwargs):
26-
if re.match(datetime_regex, v):
27-
return v
28-
raise ValueError("时间格式有误")
29-
30-
@staticmethod
31-
def offset_handler(req, resp, req_validation_error, instance):
32-
g.offset = req.context.query.count * req.context.query.page
33-
34-
35-
class LogSchema(BaseModel):
36-
message: str
37-
user_id: int
38-
username: str
39-
status_code: int
40-
method: str
41-
path: str
42-
permission: str
43-
time: datetime = Field(alias="create_time")
44-
45-
46-
class LogPageSchema(BasePageSchema):
47-
items: List[LogSchema]
48-
49-
50-
class LoginSchema(BaseModel):
51-
username: str = Field(description="用户名")
52-
password: str = Field(description="密码")
53-
captcha: Optional[str] = Field(description="验证码")
54-
55-
56-
class AccessTokenSchema(BaseModel):
57-
__root__: str = Field(description="access_token")
58-
59-
60-
class RefreshTokenSchema(BaseModel):
61-
__root__: str = Field(description="refresh_token")
62-
63-
64-
class LoginTokenSchema(BaseModel):
65-
access_token: AccessTokenSchema
66-
refresh_token: RefreshTokenSchema

app/api/cms/schema/admin.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import re
2+
from typing import List, Optional
3+
4+
from lin import BaseModel, ParameterError
5+
from pydantic import EmailStr, Field, validator
6+
7+
from app.schema import BasePageSchema, QueryPageSchema
8+
9+
10+
class ResetPasswordSchema(BaseModel):
11+
new_password: str = Field(description="新密码", min_length=6, max_length=22)
12+
confirm_password: str = Field(description="确认密码", min_length=6, max_length=22)
13+
14+
@validator("confirm_password", allow_reuse=True)
15+
def passwords_match(cls, v, values, **kwargs):
16+
if v != values["new_password"]:
17+
raise ParameterError("两次输入的密码不一致,请输入相同的密码")
18+
return v
19+
20+
21+
class GroupIdListSchema(BaseModel):
22+
group_ids: List[int] = Field(description="用户组ID列表")
23+
24+
@validator("group_ids", each_item=True)
25+
def check_group_id(cls, v, values, **kwargs):
26+
if v <= 0:
27+
raise ParameterError("用户组ID必须大于0")
28+
return v
29+
30+
31+
class RegisterSchema(ResetPasswordSchema, GroupIdListSchema):
32+
username: str = Field(description="用户名", min_length=2, max_length=10)
33+
34+
@validator("username")
35+
def check_username(cls, v, values, **kwargs):
36+
if not re.match(r"^[a-zA-Z0-9_]{2,10}$", v):
37+
raise ParameterError("用户名只能由字母、数字、下划线组成,且长度为2-10位")
38+
return v
39+
40+
41+
class AdminGroupSchema(BaseModel):
42+
id: int = Field(description="用户组ID")
43+
info: str = Field(description="用户组信息")
44+
name: str = Field(description="用户组名称")
45+
46+
47+
class AdminGroupListSchema(BaseModel):
48+
__root__: List[AdminGroupSchema]
49+
50+
51+
class AdminUserSchema(BaseModel):
52+
id: int = Field(description="用户ID")
53+
username: str = Field(description="用户名")
54+
email: Optional[EmailStr] = Field(description="邮箱")
55+
groups: List[AdminGroupSchema] = Field(description="用户组列表")
56+
57+
58+
class AdminUserPageSchema(BasePageSchema):
59+
items: List[AdminUserSchema]
60+
61+
62+
class GroupQuerySearchSchema(QueryPageSchema):
63+
group_id: Optional[int] = Field(gt=0, description="用户组ID")
64+
65+
66+
class UpdateUserInfoSchema(GroupIdListSchema):
67+
email: EmailStr = Field(description="电子邮件")
68+
69+
70+
class PermissionSchema(BaseModel):
71+
id: int = Field(description="权限ID")
72+
name: str = Field(description="权限名称")
73+
module: str = Field(description="权限所属模块")
74+
mount: bool = Field(description="是否为挂载权限")
75+
76+
77+
class AdminGroupPermissionSchema(AdminGroupSchema):
78+
permissions: List[PermissionSchema]
79+
80+
81+
class AdminGroupPermissionPageSchema(BasePageSchema):
82+
items: List[AdminGroupPermissionSchema]
83+
84+
85+
class GroupBaseSchema(BaseModel):
86+
name: str = Field(description="用户组名称")
87+
info: Optional[str] = Field(description="用户组信息")
88+
89+
90+
class CreateGroupSchema(GroupBaseSchema):
91+
permission_ids: List[int] = Field(description="权限ID列表")
92+
93+
@validator("permission_ids", each_item=True)
94+
def check_permission_id(cls, v, values, **kwargs):
95+
if v <= 0:
96+
raise ParameterError("权限ID必须大于0")
97+
return v
98+
99+
100+
class GroupIdWithPermissionIdListSchema(BaseModel):
101+
group_id: int = Field(description="用户组ID")
102+
permission_ids: List[int] = Field(description="权限ID列表")
103+
104+
@validator("permission_ids", each_item=True)
105+
def check_permission_id(cls, v, values, **kwargs):
106+
if v <= 0:
107+
raise ParameterError("权限ID必须大于0")
108+
return v

app/api/cms/schema/log.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import re
2+
from datetime import datetime
3+
from typing import List, Optional
4+
5+
from lin import BaseModel
6+
from pydantic import Field, validator
7+
8+
from app.schema import BasePageSchema, QueryPageSchema, datetime_regex
9+
10+
11+
class UsernameListSchema(BaseModel):
12+
items: List[str]
13+
14+
15+
class LogQuerySearchSchema(QueryPageSchema):
16+
keyword: Optional[str] = None
17+
name: Optional[str] = None
18+
start: Optional[str] = Field(None, description="YY-MM-DD HH:MM:SS")
19+
end: Optional[str] = Field(None, description="YY-MM-DD HH:MM:SS")
20+
21+
@validator("start", "end")
22+
def datetime_match(cls, v):
23+
if re.match(datetime_regex, v):
24+
return v
25+
raise ValueError("时间格式有误")
26+
27+
28+
class LogSchema(BaseModel):
29+
message: str
30+
user_id: int
31+
username: str
32+
status_code: int
33+
method: str
34+
path: str
35+
permission: str
36+
time: datetime = Field(alias="create_time")
37+
38+
39+
class LogPageSchema(BasePageSchema):
40+
items: List[LogSchema]

app/api/cms/schema/user.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from typing import Optional
2+
3+
from lin import BaseModel
4+
from pydantic import Field
5+
6+
7+
class LoginSchema(BaseModel):
8+
username: str = Field(description="用户名")
9+
password: str = Field(description="密码")
10+
captcha: Optional[str] = Field(description="验证码")
11+
12+
13+
class LoginTokenSchema(BaseModel):
14+
access_token: str = Field(description="access_token")
15+
refresh_token: str = Field(description="refresh_token")
16+
17+
18+
class CaptchaSchema(BaseModel):
19+
image: str = Field("", description="验证码图片base64编码")
20+
tag: str = Field("", description="验证码标记码")

0 commit comments

Comments
 (0)