76 lines
1.9 KiB
Python
76 lines
1.9 KiB
Python
from typing import List, Optional
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
from app.models.domain.articles import Article
|
||
from app.models.schemas.rwschema import RWSchema
|
||
|
||
DEFAULT_ARTICLES_LIMIT = 20
|
||
DEFAULT_ARTICLES_OFFSET = 0
|
||
|
||
|
||
class ArticleForResponse(RWSchema, Article):
|
||
"""
|
||
返回给前端的文章结构:
|
||
- 继承 Article(包含 cover、tags、author 等)
|
||
- tags 字段通过 alias 暴露为 tagList,兼容前端
|
||
"""
|
||
tags: List[str] = Field(..., alias="tagList")
|
||
|
||
|
||
class ArticleInResponse(RWSchema):
|
||
article: ArticleForResponse
|
||
|
||
|
||
class ArticleInCreate(RWSchema):
|
||
"""
|
||
创建文章时请求体:
|
||
{
|
||
"article": {
|
||
"title": "...",
|
||
"description": "...",
|
||
"body": "...",
|
||
"tagList": ["..."],
|
||
"cover": "可选封面URL"
|
||
}
|
||
}
|
||
"""
|
||
title: str
|
||
description: str
|
||
body: str
|
||
tags: List[str] = Field([], alias="tagList")
|
||
cover: Optional[str] = None
|
||
|
||
|
||
class ArticleInUpdate(RWSchema):
|
||
"""
|
||
更新文章时请求体(全部可选):
|
||
- 不传的字段不改
|
||
- cover:
|
||
- 不传:不改
|
||
- 传 null / "":清空封面(配合 repo 的 cover_provided 使用)
|
||
- 传字符串:更新为新封面
|
||
"""
|
||
title: Optional[str] = None
|
||
description: Optional[str] = None
|
||
body: Optional[str] = None
|
||
cover: Optional[str] = None
|
||
is_top: Optional[bool] = None
|
||
is_featured: Optional[bool] = None
|
||
sort_weight: Optional[int] = None
|
||
|
||
|
||
class ListOfArticlesInResponse(RWSchema):
|
||
articles: List[ArticleForResponse]
|
||
articles_count: int
|
||
|
||
|
||
class ArticlesFilters(BaseModel):
|
||
tag: Optional[str] = None
|
||
tags: Optional[List[str]] = None
|
||
author: Optional[str] = None
|
||
favorited: Optional[str] = None
|
||
search: Optional[str] = None
|
||
limit: int = Field(DEFAULT_ARTICLES_LIMIT, ge=1)
|
||
offset: int = Field(DEFAULT_ARTICLES_OFFSET, ge=0)
|