diff --git a/article/schema.py b/article/schema.py index 9f6c698..67f71f8 100644 --- a/article/schema.py +++ b/article/schema.py @@ -2,7 +2,6 @@ from datetime import datetime from typing import Optional, List, Generic, T from ninja import Schema -from pydantic import Field # --- 假设的关联模型 Schema --- @@ -16,47 +15,49 @@ class SectionSchema(Schema): title: str # 假设 MainMenu 有 name 字段 -class AttachmentSchema(Schema): +class ArticleAttachmentOut(Schema): id: int - file: str # 返回文件 URL 路径,如 "articles/attachments/2026/04/03/file.pdf" + file: str -class PaginatedResponseSchema(Schema, Generic[T]): - items: List[T] - total: int - page: int - per_page: int - total_pages: int - - -# --- Article 主 Schema --- -class ArticleSchema(Schema): +class ArticleListOut(Schema): id: int title: str - content: str - cover: Optional[str] = None # 图片 URL 路径 + + section: SectionSchema + + author: AuthorSchema + + cover: Optional[str] = None is_contribution: bool is_published: bool - created_at: datetime - updated_at: datetime - - # 关联字段 - author: Optional[AuthorSchema] = None - section: Optional[SectionSchema] = None - attachments: List[AttachmentSchema] = Field(default_factory=list) -# --- 创建文章用的 Schema (不含只读字段) --- -class ArticleCreateSchema(Schema): +class ArticleDetailOut(Schema): + id: int title: str - section_id: Optional[int] = None # 外键通过 ID 传递 + + section: SectionSchema + + author: AuthorSchema + + content: str + cover: Optional[str] = None + + is_contribution: bool + is_published: bool + + attachments: List[ArticleAttachmentOut] = [] + + +class ArticleCreate(Schema): + title: str + section_id: Optional[int] = None + author_id: Optional[int] = None content: str - cover: Optional[str] = None # 注意:文件上传通常需单独处理,此处仅为文本路径示例 is_contribution: bool = False is_published: bool = True -# --- 更新文章用的 Schema --- -class ArticleUpdateSchema(ArticleCreateSchema): - title: Optional[str] = None - content: Optional[str] = None +class ArticleUpdate(ArticleCreate): + pass diff --git a/article/views.py b/article/views.py index bf74a1e..0e2fbfc 100644 --- a/article/views.py +++ b/article/views.py @@ -1,34 +1,50 @@ from typing import List +from django.shortcuts import get_object_or_404 from ninja import Router from ninja.pagination import paginate, PageNumberPagination from article.models import Article -from article.schema import ArticleSchema, ArticleCreateSchema +from article.schema import ArticleUpdate, ArticleCreate, ArticleListOut, ArticleDetailOut # Create your views here. # Create your views here. -router = Router(tags=['content']) +router = Router(tags=['Article']) -@router.get("/article", response=List[ArticleSchema], description="获取文章列表") -@paginate(PageNumberPagination, page_size=50) -def list_articles(request, ): - # 安全校验 per_page(防止过大 - queryset = Article.objects.prefetch_related('attachments').select_related('author', 'section') - return queryset +@router.get("/article/", response=List[ArticleListOut], description="获取文章列表") +@paginate(PageNumberPagination, page_size=20) +def list_articles(request, title: str = '', section_id: int = 0): + qs = (Article.objects.filter(title__contains=title).prefetch_related('attachments') + .select_related('author', 'section').order_by("-id")) + if section_id > 0: + return qs.filter(section_id=section_id) + return qs -@router.post("/article", response=ArticleSchema) -def create_article(request, payload: ArticleCreateSchema): - # 注意:文件上传需额外处理(此处简化) - article = Article.objects.create( - title=payload.title, - section_id=payload.section_id, - author=request.auth, # 假设认证用户是作者 - content=payload.content, - is_contribution=payload.is_contribution, - is_published=payload.is_published, - ) +@router.get("/article/{id}", response=ArticleDetailOut) +def get_article(request, id: int): + return get_object_or_404(Article.objects.prefetch_related("attachments"), id=id) + + +@router.post("/article/", response=ArticleDetailOut) +def create_article(request, data: ArticleCreate): + article = Article.objects.create(**data.dict()) return article + + +@router.put("/article/{id}", response=ArticleDetailOut) +def update_article(request, id: int, data: ArticleUpdate): + article = get_object_or_404(Article, id=id) + for attr, value in data.dict().items(): + setattr(article, attr, value) + article.save() + return article + + +@router.delete("/article/{id}") +def delete_article(request, id: int): + article = get_object_or_404(Article, id=id) + article.delete() + return {"success": True}