update. 更新文章接口

This commit is contained in:
ngfchl
2026-04-08 15:27:21 +08:00
parent 5670ca57e6
commit 2ed7904ada
2 changed files with 66 additions and 49 deletions
+31 -30
View File
@@ -2,7 +2,6 @@ from datetime import datetime
from typing import Optional, List, Generic, T from typing import Optional, List, Generic, T
from ninja import Schema from ninja import Schema
from pydantic import Field
# --- 假设的关联模型 Schema --- # --- 假设的关联模型 Schema ---
@@ -16,47 +15,49 @@ class SectionSchema(Schema):
title: str # 假设 MainMenu 有 name 字段 title: str # 假设 MainMenu 有 name 字段
class AttachmentSchema(Schema): class ArticleAttachmentOut(Schema):
id: int id: int
file: str # 返回文件 URL 路径,如 "articles/attachments/2026/04/03/file.pdf" file: str
class PaginatedResponseSchema(Schema, Generic[T]): class ArticleListOut(Schema):
items: List[T]
total: int
page: int
per_page: int
total_pages: int
# --- Article 主 Schema ---
class ArticleSchema(Schema):
id: int id: int
title: str title: str
content: str
cover: Optional[str] = None # 图片 URL 路径 section: SectionSchema
author: AuthorSchema
cover: Optional[str] = None
is_contribution: bool is_contribution: bool
is_published: 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 ArticleDetailOut(Schema):
class ArticleCreateSchema(Schema): id: int
title: str 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 content: str
cover: Optional[str] = None # 注意:文件上传通常需单独处理,此处仅为文本路径示例
is_contribution: bool = False is_contribution: bool = False
is_published: bool = True is_published: bool = True
# --- 更新文章用的 Schema --- class ArticleUpdate(ArticleCreate):
class ArticleUpdateSchema(ArticleCreateSchema): pass
title: Optional[str] = None
content: Optional[str] = None
+35 -19
View File
@@ -1,34 +1,50 @@
from typing import List from typing import List
from django.shortcuts import get_object_or_404
from ninja import Router from ninja import Router
from ninja.pagination import paginate, PageNumberPagination from ninja.pagination import paginate, PageNumberPagination
from article.models import Article 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.
# Create your views here. # Create your views here.
router = Router(tags=['content']) router = Router(tags=['Article'])
@router.get("/article", response=List[ArticleSchema], description="获取文章列表") @router.get("/article/", response=List[ArticleListOut], description="获取文章列表")
@paginate(PageNumberPagination, page_size=50) @paginate(PageNumberPagination, page_size=20)
def list_articles(request, ): def list_articles(request, title: str = '', section_id: int = 0):
# 安全校验 per_page(防止过大 qs = (Article.objects.filter(title__contains=title).prefetch_related('attachments')
queryset = Article.objects.prefetch_related('attachments').select_related('author', 'section') .select_related('author', 'section').order_by("-id"))
return queryset if section_id > 0:
return qs.filter(section_id=section_id)
return qs
@router.post("/article", response=ArticleSchema) @router.get("/article/{id}", response=ArticleDetailOut)
def create_article(request, payload: ArticleCreateSchema): def get_article(request, id: int):
# 注意:文件上传需额外处理(此处简化) return get_object_or_404(Article.objects.prefetch_related("attachments"), id=id)
article = Article.objects.create(
title=payload.title,
section_id=payload.section_id, @router.post("/article/", response=ArticleDetailOut)
author=request.auth, # 假设认证用户是作者 def create_article(request, data: ArticleCreate):
content=payload.content, article = Article.objects.create(**data.dict())
is_contribution=payload.is_contribution,
is_published=payload.is_published,
)
return article 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}