From c87022793e0e1290b304486ba0e56336800a26a1 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Wed, 22 Oct 2025 20:29:12 +0800 Subject: [PATCH] fix --- .../migrations/0002_remove_is_public_field.py | 17 +++++ .../migrations/0003_remove_badge_level.py | 17 +++++ problemset/models.py | 4 -- problemset/serializers.py | 27 +++++-- problemset/urls/admin.py | 2 +- problemset/views/admin.py | 72 ++++++++++++++++++- problemset/views/oj.py | 21 ++---- 7 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 problemset/migrations/0002_remove_is_public_field.py create mode 100644 problemset/migrations/0003_remove_badge_level.py diff --git a/problemset/migrations/0002_remove_is_public_field.py b/problemset/migrations/0002_remove_is_public_field.py new file mode 100644 index 0000000..07866f9 --- /dev/null +++ b/problemset/migrations/0002_remove_is_public_field.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-10-22 11:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('problemset', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='problemset', + name='is_public', + ), + ] diff --git a/problemset/migrations/0003_remove_badge_level.py b/problemset/migrations/0003_remove_badge_level.py new file mode 100644 index 0000000..01541ff --- /dev/null +++ b/problemset/migrations/0003_remove_badge_level.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-10-22 12:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('problemset', '0002_remove_is_public_field'), + ] + + operations = [ + migrations.RemoveField( + model_name='problemsetbadge', + name='level', + ), + ] diff --git a/problemset/models.py b/problemset/models.py index 3d74d6a..1cb74ad 100644 --- a/problemset/models.py +++ b/problemset/models.py @@ -20,8 +20,6 @@ class ProblemSet(models.Model): last_update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") # 是否可见 visible = models.BooleanField(default=True, verbose_name="是否可见") - # 是否公开(所有用户都可以看到) - is_public = models.BooleanField(default=True, verbose_name="是否公开") # 题单难度等级 difficulty = models.TextField(default="Easy", verbose_name="难度等级") # 题单状态 @@ -81,8 +79,6 @@ class ProblemSetBadge(models.Model): verbose_name="获得条件类型" ) # all_problems, problem_count, score condition_value = models.IntegerField(default=0, verbose_name="条件值") - # 奖章等级 - level = models.IntegerField(default=1, verbose_name="奖章等级") class Meta: db_table = "problemset_badge" diff --git a/problemset/serializers.py b/problemset/serializers.py index 422953f..0dcae88 100644 --- a/problemset/serializers.py +++ b/problemset/serializers.py @@ -56,6 +56,7 @@ class ProblemSetListSerializer(serializers.ModelSerializer): "status", "problems_count", "user_progress", + "visible", ] def get_problems_count(self, obj): @@ -100,7 +101,6 @@ class CreateProblemSetSerializer(serializers.Serializer): title = serializers.CharField(max_length=200) description = serializers.CharField() difficulty = serializers.CharField(default="Easy") - is_public = serializers.BooleanField(default=True) status = serializers.CharField(default="active") @@ -111,7 +111,6 @@ class EditProblemSetSerializer(serializers.Serializer): title = serializers.CharField(max_length=200, required=False) description = serializers.CharField(required=False) difficulty = serializers.CharField(required=False) - is_public = serializers.BooleanField(required=False) status = serializers.CharField(required=False) visible = serializers.BooleanField(required=False) @@ -135,14 +134,22 @@ class ProblemSetProblemSerializer(serializers.ModelSerializer): class AddProblemToSetSerializer(serializers.Serializer): """添加题目到题单序列化器""" - problemset_id = serializers.IntegerField() - problem_id = serializers.IntegerField() + problem_id = serializers.CharField() order = serializers.IntegerField(default=0) is_required = serializers.BooleanField(default=True) score = serializers.IntegerField(default=0) hint = serializers.CharField(required=False, allow_blank=True) +class EditProblemInSetSerializer(serializers.Serializer): + """编辑题单中的题目序列化器""" + + order = serializers.IntegerField(required=False) + is_required = serializers.BooleanField(required=False) + score = serializers.IntegerField(required=False) + hint = serializers.CharField(required=False, allow_blank=True) + + class ProblemSetBadgeSerializer(serializers.ModelSerializer): """题单奖章序列化器""" @@ -153,14 +160,20 @@ class ProblemSetBadgeSerializer(serializers.ModelSerializer): class CreateProblemSetBadgeSerializer(serializers.Serializer): """创建题单奖章序列化器""" - - problemset_id = serializers.IntegerField() name = serializers.CharField(max_length=100) description = serializers.CharField() icon = serializers.CharField() condition_type = serializers.CharField() # all_problems, problem_count, score condition_value = serializers.IntegerField() - level = serializers.IntegerField(default=1) + + +class EditProblemSetBadgeSerializer(serializers.Serializer): + """编辑题单奖章序列化器""" + name = serializers.CharField(max_length=100, required=False) + description = serializers.CharField(required=False) + icon = serializers.CharField(required=False) + condition_type = serializers.CharField(required=False) # all_problems, problem_count, score + condition_value = serializers.IntegerField(required=False) class ProblemSetProgressSerializer(serializers.ModelSerializer): diff --git a/problemset/urls/admin.py b/problemset/urls/admin.py index 1955436..140c32b 100644 --- a/problemset/urls/admin.py +++ b/problemset/urls/admin.py @@ -24,7 +24,7 @@ urlpatterns = [ name="admin_problemset_problems_api", ), path( - "problemset//problems//", + "problemset//problems//", ProblemSetProblemAdminAPI.as_view(), name="admin_problemset_problem_detail_api", ), diff --git a/problemset/views/admin.py b/problemset/views/admin.py index 3e80c38..6de8ef9 100644 --- a/problemset/views/admin.py +++ b/problemset/views/admin.py @@ -16,8 +16,10 @@ from problemset.serializers import ( EditProblemSetSerializer, ProblemSetProblemSerializer, AddProblemToSetSerializer, + EditProblemInSetSerializer, ProblemSetBadgeSerializer, CreateProblemSetBadgeSerializer, + EditProblemSetBadgeSerializer, ProblemSetProgressSerializer, ) from problem.models import Problem @@ -152,7 +154,7 @@ class ProblemSetProblemAdminAPI(APIView): data = request.data try: - problem = Problem.objects.get(id=data["problem_id"]) + problem = Problem.objects.get(_id=data["problem_id"]) except Problem.DoesNotExist: return self.error("题目不存在") @@ -174,7 +176,38 @@ class ProblemSetProblemAdminAPI(APIView): return self.success("题目已添加到题单") @super_admin_required - def delete(self, request, problem_set_id, problem_id): + @validate_serializer(EditProblemInSetSerializer) + def put(self, request, problem_set_id, problem_set_problem_id): + """编辑题单中的题目(管理员)""" + try: + problem_set = ProblemSet.objects.get(id=problem_set_id) + ensure_created_by(problem_set, request.user) + except ProblemSet.DoesNotExist: + return self.error("题单不存在") + + try: + problem_set_problem = ProblemSetProblem.objects.get( + id=problem_set_problem_id, problemset=problem_set + ) + except ProblemSetProblem.DoesNotExist: + return self.error("题目不在该题单中") + + data = request.data + # 更新题目属性 + if 'order' in data: + problem_set_problem.order = data['order'] + if 'is_required' in data: + problem_set_problem.is_required = data['is_required'] + if 'score' in data: + problem_set_problem.score = data['score'] + if 'hint' in data: + problem_set_problem.hint = data['hint'] + + problem_set_problem.save() + return self.success("题目已更新") + + @super_admin_required + def delete(self, request, problem_set_id, problem_set_problem_id): """从题单中移除题目(管理员)""" try: problem_set = ProblemSet.objects.get(id=problem_set_id) @@ -184,7 +217,7 @@ class ProblemSetProblemAdminAPI(APIView): try: problem_set_problem = ProblemSetProblem.objects.get( - problemset=problem_set, problem_id=problem_id + id=problem_set_problem_id, problemset=problem_set ) problem_set_problem.delete() return self.success("题目已从题单中移除") @@ -224,6 +257,39 @@ class ProblemSetBadgeAdminAPI(APIView): return self.success(ProblemSetBadgeSerializer(badge).data) + @super_admin_required + @validate_serializer(EditProblemSetBadgeSerializer) + def put(self, request, problem_set_id, badge_id): + """编辑题单奖章(管理员)""" + try: + problem_set = ProblemSet.objects.get(id=problem_set_id) + ensure_created_by(problem_set, request.user) + except ProblemSet.DoesNotExist: + return self.error("题单不存在") + + try: + badge = ProblemSetBadge.objects.get(id=badge_id, problemset=problem_set) + except ProblemSetBadge.DoesNotExist: + return self.error("奖章不存在") + + data = request.data + # 更新奖章属性 + if 'name' in data: + badge.name = data['name'] + if 'description' in data: + badge.description = data['description'] + if 'icon' in data: + badge.icon = data['icon'] + if 'condition_type' in data: + badge.condition_type = data['condition_type'] + if 'condition_value' in data: + badge.condition_value = data['condition_value'] + if 'level' in data: + badge.level = data['level'] + + badge.save() + return self.success("奖章已更新") + @super_admin_required def delete(self, request, problem_set_id, badge_id): """删除题单奖章(管理员)""" diff --git a/problemset/views/oj.py b/problemset/views/oj.py index 9ebe1ae..da489ce 100644 --- a/problemset/views/oj.py +++ b/problemset/views/oj.py @@ -50,9 +50,7 @@ class ProblemSetAPI(APIView): if status_filter: problem_sets = problem_sets.filter(status=status_filter) - # 只显示公开的题单,除非是管理员 - if not request.user.is_authenticated or not request.user.is_admin_role(): - problem_sets = problem_sets.filter(is_public=True) + # 所有用户都可以看到可见的题单 # 排序 sort = request.GET.get("sort") @@ -83,12 +81,7 @@ class ProblemSetDetailAPI(APIView): except ProblemSet.DoesNotExist: return self.error("题单不存在") - # 检查权限 - if not problem_set.is_public and not ( - request.user.is_authenticated and request.user.is_admin_role() - ): - return self.error("无权限访问该题单") - + # 题单可见即可访问 serializer = ProblemSetSerializer(problem_set, context={"request": request}) return self.success(serializer.data) @@ -139,11 +132,7 @@ class ProblemSetProblemAPI(APIView): except ProblemSet.DoesNotExist: return self.error("题单不存在") - # 检查权限 - if not problem_set.is_public and not ( - request.user.is_authenticated and request.user.is_admin_role() - ): - return self.error("无权限访问该题单") + # 题单可见即可访问 problems = ProblemSetProblem.objects.filter(problemset=problem_set).order_by( "order" @@ -221,9 +210,7 @@ class ProblemSetProgressAPI(APIView): except ProblemSet.DoesNotExist: return self.error("题单不存在") - # 检查权限 - if not problem_set.is_public and not request.user.is_admin_role(): - return self.error("无权限加入该题单") + # 题单可见即可加入 # 检查是否已经加入 if ProblemSetProgress.objects.filter(