diff --git a/news/schema.py b/news/schema.py new file mode 100644 index 0000000..364553e --- /dev/null +++ b/news/schema.py @@ -0,0 +1,49 @@ +from ninja import Schema +from typing import Optional +from pydantic import constr + +# 新闻模块 +class NewsSectionSchema(Schema): + id: int + title: str + code: str + order: int + visible: bool + +class NewsSectionCreateSchema(Schema): + title: constr(max_length=100) + code: constr(max_length=50) + order: Optional[int] = 0 + visible: Optional[bool] = True + +class NewsSectionUpdateSchema(Schema): + title: Optional[constr(max_length=100)] + code: Optional[constr(max_length=50)] + order: Optional[int] + visible: Optional[bool] + +# 新闻内容 +class NewsSchema(Schema): + id: int + title: str + section_id: int + author_id: Optional[int] + content: str + cover: Optional[str] + is_published: bool + +class NewsCreateSchema(Schema): + title: constr(max_length=200) + section_id: int + author_id: Optional[int] + content: str + cover: Optional[str] + is_published: Optional[bool] = True + +class NewsUpdateSchema(Schema): + title: Optional[constr(max_length=200)] + section_id: Optional[int] + author_id: Optional[int] + content: Optional[str] + cover: Optional[str] + is_published: Optional[bool] diff --git a/news/views.py b/news/views.py index 91ea44a..6f2e409 100644 --- a/news/views.py +++ b/news/views.py @@ -1,3 +1,89 @@ from django.shortcuts import render # Create your views here. +from ninja import Router +from django.shortcuts import get_object_or_404 +from typing import List + +from ninja.pagination import paginate, PageNumberPagination + +from .models import NewsSection, News +from .schema import ( + NewsSectionSchema, NewsSectionCreateSchema, NewsSectionUpdateSchema, + NewsSchema, NewsCreateSchema, NewsUpdateSchema +) + +router = Router(tags=['news']) + + +# ================= 新闻模块接口 ================= + +@router.get("/news_section/", response=List[NewsSectionSchema]) +@paginate(PageNumberPagination, page_size=20) +def list_sections(request): + return NewsSection.objects.all() + + +@router.get("/news_section/{section_id}", response=NewsSectionSchema) +def retrieve_section(request, section_id: int): + return get_object_or_404(NewsSection, id=section_id) + + +@router.post("/news_section/", response=NewsSectionSchema) +def create_section(request, data: NewsSectionCreateSchema): + section = NewsSection.objects.create(**data.dict()) + return section + + +@router.put("/news_section/{section_id}", response=NewsSectionSchema) +def update_section(request, section_id: int, data: NewsSectionUpdateSchema): + section = get_object_or_404(NewsSection, id=section_id) + for attr, value in data.dict(exclude_unset=True).items(): + setattr(section, attr, value) + section.save() + return section + + +@router.delete("/news_section/{section_id}", response={"success": bool}) +def delete_section(request, section_id: int): + section = get_object_or_404(NewsSection, id=section_id) + section.delete() + return {"success": True} + + +# ================= 新闻接口 ================= + +@router.get("/news/", response=List[NewsSchema]) +@paginate(PageNumberPagination, page_size=20) +def list_news(request, section_id: int = 0, title: str = ''): + news = News.objects.filter(title__contains=title) + if section_id > 0: + return news.filter(section_id=section_id).all() + return news + + +@router.get("/news/{news_id}", response=NewsSchema) +def retrieve_news(request, news_id: int): + return get_object_or_404(News, id=news_id) + + +@router.post("/news/", response=NewsSchema) +def create_news(request, data: NewsCreateSchema): + news = News.objects.create(**data.dict()) + return news + + +@router.put("/news/{news_id}", response=NewsSchema) +def update_news(request, news_id: int, data: NewsUpdateSchema): + news = get_object_or_404(News, id=news_id) + for attr, value in data.dict(exclude_unset=True).items(): + setattr(news, attr, value) + news.save() + return news + + +@router.delete("/news/{news_id}", response={"success": bool}) +def delete_news(request, news_id: int): + news = get_object_or_404(News, id=news_id) + news.delete() + return {"success": True}