From fdbe06a07793cc7b6124637bea43d2745e12795a Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Wed, 4 Mar 2026 00:04:39 +0800 Subject: [PATCH] update --- api/urls.py | 1 + task/challenge.py | 63 +++++++++++++++++++ ...ask_options_alter_task_display_and_more.py | 26 ++++++++ task/models.py | 5 +- task/schemas.py | 23 ++++++- 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 task/challenge.py create mode 100644 task/migrations/0005_alter_task_options_alter_task_display_and_more.py diff --git a/api/urls.py b/api/urls.py index 4217da6..4d44df9 100644 --- a/api/urls.py +++ b/api/urls.py @@ -25,6 +25,7 @@ api = NinjaAPI() api.add_router("account/", "account.api.router") api.add_router("tutorial/", "task.tutorial.router") +api.add_router("challenge/", "task.challenge.router") api.add_router("submission/", "submission.api.router") api.add_router("upload/", "utils.upload.router") diff --git a/task/challenge.py b/task/challenge.py new file mode 100644 index 0000000..dd96aaf --- /dev/null +++ b/task/challenge.py @@ -0,0 +1,63 @@ +from typing import List +from ninja import Router +from django.shortcuts import get_object_or_404 +from account.decorators import super_required +from .schemas import ChallengeAll, ChallengeIn, ChallengeSlim +from .models import Challenge + +router = Router() + + +@router.get("/list", response=List[ChallengeSlim]) +@super_required +def challenge(request): + """ + 后台显示所有的列表 + """ + return Challenge.objects.all() + + +@router.get("/display", response=List[ChallengeSlim]) +def get_all_public_display(request): + """ + 前台显示所有公开的挑战 + """ + return Challenge.objects.filter(is_public=True) + + +@router.get("/{display}", response=ChallengeAll) +def get(request, display: int): + return get_object_or_404(Challenge, display=display) + + +@router.post("/") +@super_required +def create_or_update(request, payload: ChallengeIn): + try: + item = Challenge.objects.get(display=payload.display) + item.title = payload.title + item.content = payload.content + item.score = payload.score + item.is_public = payload.is_public + item.save() + return {"message": "更新成功"} + except Challenge.DoesNotExist: + Challenge.objects.create(**payload.dict()) + return {"message": "创建成功"} + + +@router.put("/public/{display}") +@super_required +def toggle_public(request, display: int): + item = get_object_or_404(Challenge, display=display) + item.is_public = not item.is_public + item.save() + label = "公开" if item.is_public else "隐藏" + return {"message": f"【{item.display}】{item.title} 已{label}"} + + +@router.delete("/{display}") +@super_required +def remove(request, display: int): + Challenge.objects.filter(display=display).delete() + return {"message": "删除成功"} diff --git a/task/migrations/0005_alter_task_options_alter_task_display_and_more.py b/task/migrations/0005_alter_task_options_alter_task_display_and_more.py new file mode 100644 index 0000000..fc9d16c --- /dev/null +++ b/task/migrations/0005_alter_task_options_alter_task_display_and_more.py @@ -0,0 +1,26 @@ +# Generated by Django 6.0.1 on 2026-03-03 14:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('task', '0004_alter_task_task_type'), + ] + + operations = [ + migrations.AlterModelOptions( + name='task', + options={}, + ), + migrations.AlterField( + model_name='task', + name='display', + field=models.IntegerField(db_index=True, verbose_name='序号'), + ), + migrations.AlterUniqueTogether( + name='task', + unique_together={('display', 'task_type')}, + ), + ] diff --git a/task/models.py b/task/models.py index ce4f7c7..c781295 100644 --- a/task/models.py +++ b/task/models.py @@ -8,7 +8,7 @@ class TaskTypeChoices(models.TextChoices): class Task(TimeStampedModel): - display = models.IntegerField(unique=True, db_index=True, verbose_name="序号") + display = models.IntegerField(db_index=True, verbose_name="序号") title = models.CharField(max_length=100, verbose_name="标题") content = models.TextField(verbose_name="内容") task_type = models.CharField( @@ -19,6 +19,9 @@ class Task(TimeStampedModel): ) is_public = models.BooleanField(default=False, verbose_name="是否公开") + class Meta: + unique_together = ("display", "task_type") + def save(self, *args, **kwargs): if not self.task_type: self.task_type = self.__class__.__name__.lower() diff --git a/task/schemas.py b/task/schemas.py index fa30085..ae81adc 100644 --- a/task/schemas.py +++ b/task/schemas.py @@ -1,5 +1,5 @@ from ninja import Schema, ModelSchema -from .models import Tutorial +from .models import Tutorial, Challenge class TutorialSlim(Schema): @@ -19,3 +19,24 @@ class TutorialIn(Schema): title: str content: str is_public: bool = False + + +class ChallengeSlim(Schema): + display: int + title: str + score: int + is_public: bool + + +class ChallengeAll(ModelSchema): + class Meta: + model = Challenge + fields = "__all__" + + +class ChallengeIn(Schema): + display: int + title: str + content: str + score: int = 0 + is_public: bool = False