fix
This commit is contained in:
17
problemset/migrations/0002_remove_is_public_field.py
Normal file
17
problemset/migrations/0002_remove_is_public_field.py
Normal file
@@ -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',
|
||||||
|
),
|
||||||
|
]
|
||||||
17
problemset/migrations/0003_remove_badge_level.py
Normal file
17
problemset/migrations/0003_remove_badge_level.py
Normal file
@@ -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',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -20,8 +20,6 @@ class ProblemSet(models.Model):
|
|||||||
last_update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
|
last_update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
|
||||||
# 是否可见
|
# 是否可见
|
||||||
visible = models.BooleanField(default=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="难度等级")
|
difficulty = models.TextField(default="Easy", verbose_name="难度等级")
|
||||||
# 题单状态
|
# 题单状态
|
||||||
@@ -81,8 +79,6 @@ class ProblemSetBadge(models.Model):
|
|||||||
verbose_name="获得条件类型"
|
verbose_name="获得条件类型"
|
||||||
) # all_problems, problem_count, score
|
) # all_problems, problem_count, score
|
||||||
condition_value = models.IntegerField(default=0, verbose_name="条件值")
|
condition_value = models.IntegerField(default=0, verbose_name="条件值")
|
||||||
# 奖章等级
|
|
||||||
level = models.IntegerField(default=1, verbose_name="奖章等级")
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "problemset_badge"
|
db_table = "problemset_badge"
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class ProblemSetListSerializer(serializers.ModelSerializer):
|
|||||||
"status",
|
"status",
|
||||||
"problems_count",
|
"problems_count",
|
||||||
"user_progress",
|
"user_progress",
|
||||||
|
"visible",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_problems_count(self, obj):
|
def get_problems_count(self, obj):
|
||||||
@@ -100,7 +101,6 @@ class CreateProblemSetSerializer(serializers.Serializer):
|
|||||||
title = serializers.CharField(max_length=200)
|
title = serializers.CharField(max_length=200)
|
||||||
description = serializers.CharField()
|
description = serializers.CharField()
|
||||||
difficulty = serializers.CharField(default="Easy")
|
difficulty = serializers.CharField(default="Easy")
|
||||||
is_public = serializers.BooleanField(default=True)
|
|
||||||
status = serializers.CharField(default="active")
|
status = serializers.CharField(default="active")
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +111,6 @@ class EditProblemSetSerializer(serializers.Serializer):
|
|||||||
title = serializers.CharField(max_length=200, required=False)
|
title = serializers.CharField(max_length=200, required=False)
|
||||||
description = serializers.CharField(required=False)
|
description = serializers.CharField(required=False)
|
||||||
difficulty = serializers.CharField(required=False)
|
difficulty = serializers.CharField(required=False)
|
||||||
is_public = serializers.BooleanField(required=False)
|
|
||||||
status = serializers.CharField(required=False)
|
status = serializers.CharField(required=False)
|
||||||
visible = serializers.BooleanField(required=False)
|
visible = serializers.BooleanField(required=False)
|
||||||
|
|
||||||
@@ -135,14 +134,22 @@ class ProblemSetProblemSerializer(serializers.ModelSerializer):
|
|||||||
class AddProblemToSetSerializer(serializers.Serializer):
|
class AddProblemToSetSerializer(serializers.Serializer):
|
||||||
"""添加题目到题单序列化器"""
|
"""添加题目到题单序列化器"""
|
||||||
|
|
||||||
problemset_id = serializers.IntegerField()
|
problem_id = serializers.CharField()
|
||||||
problem_id = serializers.IntegerField()
|
|
||||||
order = serializers.IntegerField(default=0)
|
order = serializers.IntegerField(default=0)
|
||||||
is_required = serializers.BooleanField(default=True)
|
is_required = serializers.BooleanField(default=True)
|
||||||
score = serializers.IntegerField(default=0)
|
score = serializers.IntegerField(default=0)
|
||||||
hint = serializers.CharField(required=False, allow_blank=True)
|
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):
|
class ProblemSetBadgeSerializer(serializers.ModelSerializer):
|
||||||
"""题单奖章序列化器"""
|
"""题单奖章序列化器"""
|
||||||
|
|
||||||
@@ -153,14 +160,20 @@ class ProblemSetBadgeSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class CreateProblemSetBadgeSerializer(serializers.Serializer):
|
class CreateProblemSetBadgeSerializer(serializers.Serializer):
|
||||||
"""创建题单奖章序列化器"""
|
"""创建题单奖章序列化器"""
|
||||||
|
|
||||||
problemset_id = serializers.IntegerField()
|
|
||||||
name = serializers.CharField(max_length=100)
|
name = serializers.CharField(max_length=100)
|
||||||
description = serializers.CharField()
|
description = serializers.CharField()
|
||||||
icon = serializers.CharField()
|
icon = serializers.CharField()
|
||||||
condition_type = serializers.CharField() # all_problems, problem_count, score
|
condition_type = serializers.CharField() # all_problems, problem_count, score
|
||||||
condition_value = serializers.IntegerField()
|
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):
|
class ProblemSetProgressSerializer(serializers.ModelSerializer):
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ urlpatterns = [
|
|||||||
name="admin_problemset_problems_api",
|
name="admin_problemset_problems_api",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"problemset/<int:problem_set_id>/problems/<int:problem_id>/",
|
"problemset/<int:problem_set_id>/problems/<int:problem_set_problem_id>/",
|
||||||
ProblemSetProblemAdminAPI.as_view(),
|
ProblemSetProblemAdminAPI.as_view(),
|
||||||
name="admin_problemset_problem_detail_api",
|
name="admin_problemset_problem_detail_api",
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ from problemset.serializers import (
|
|||||||
EditProblemSetSerializer,
|
EditProblemSetSerializer,
|
||||||
ProblemSetProblemSerializer,
|
ProblemSetProblemSerializer,
|
||||||
AddProblemToSetSerializer,
|
AddProblemToSetSerializer,
|
||||||
|
EditProblemInSetSerializer,
|
||||||
ProblemSetBadgeSerializer,
|
ProblemSetBadgeSerializer,
|
||||||
CreateProblemSetBadgeSerializer,
|
CreateProblemSetBadgeSerializer,
|
||||||
|
EditProblemSetBadgeSerializer,
|
||||||
ProblemSetProgressSerializer,
|
ProblemSetProgressSerializer,
|
||||||
)
|
)
|
||||||
from problem.models import Problem
|
from problem.models import Problem
|
||||||
@@ -152,7 +154,7 @@ class ProblemSetProblemAdminAPI(APIView):
|
|||||||
|
|
||||||
data = request.data
|
data = request.data
|
||||||
try:
|
try:
|
||||||
problem = Problem.objects.get(id=data["problem_id"])
|
problem = Problem.objects.get(_id=data["problem_id"])
|
||||||
except Problem.DoesNotExist:
|
except Problem.DoesNotExist:
|
||||||
return self.error("题目不存在")
|
return self.error("题目不存在")
|
||||||
|
|
||||||
@@ -174,7 +176,38 @@ class ProblemSetProblemAdminAPI(APIView):
|
|||||||
return self.success("题目已添加到题单")
|
return self.success("题目已添加到题单")
|
||||||
|
|
||||||
@super_admin_required
|
@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:
|
try:
|
||||||
problem_set = ProblemSet.objects.get(id=problem_set_id)
|
problem_set = ProblemSet.objects.get(id=problem_set_id)
|
||||||
@@ -184,7 +217,7 @@ class ProblemSetProblemAdminAPI(APIView):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
problem_set_problem = ProblemSetProblem.objects.get(
|
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()
|
problem_set_problem.delete()
|
||||||
return self.success("题目已从题单中移除")
|
return self.success("题目已从题单中移除")
|
||||||
@@ -224,6 +257,39 @@ class ProblemSetBadgeAdminAPI(APIView):
|
|||||||
|
|
||||||
return self.success(ProblemSetBadgeSerializer(badge).data)
|
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
|
@super_admin_required
|
||||||
def delete(self, request, problem_set_id, badge_id):
|
def delete(self, request, problem_set_id, badge_id):
|
||||||
"""删除题单奖章(管理员)"""
|
"""删除题单奖章(管理员)"""
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ class ProblemSetAPI(APIView):
|
|||||||
if status_filter:
|
if status_filter:
|
||||||
problem_sets = problem_sets.filter(status=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")
|
sort = request.GET.get("sort")
|
||||||
@@ -83,12 +81,7 @@ class ProblemSetDetailAPI(APIView):
|
|||||||
except ProblemSet.DoesNotExist:
|
except ProblemSet.DoesNotExist:
|
||||||
return self.error("题单不存在")
|
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})
|
serializer = ProblemSetSerializer(problem_set, context={"request": request})
|
||||||
return self.success(serializer.data)
|
return self.success(serializer.data)
|
||||||
|
|
||||||
@@ -139,11 +132,7 @@ class ProblemSetProblemAPI(APIView):
|
|||||||
except ProblemSet.DoesNotExist:
|
except ProblemSet.DoesNotExist:
|
||||||
return self.error("题单不存在")
|
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(
|
problems = ProblemSetProblem.objects.filter(problemset=problem_set).order_by(
|
||||||
"order"
|
"order"
|
||||||
@@ -221,9 +210,7 @@ class ProblemSetProgressAPI(APIView):
|
|||||||
except ProblemSet.DoesNotExist:
|
except ProblemSet.DoesNotExist:
|
||||||
return self.error("题单不存在")
|
return self.error("题单不存在")
|
||||||
|
|
||||||
# 检查权限
|
# 题单可见即可加入
|
||||||
if not problem_set.is_public and not request.user.is_admin_role():
|
|
||||||
return self.error("无权限加入该题单")
|
|
||||||
|
|
||||||
# 检查是否已经加入
|
# 检查是否已经加入
|
||||||
if ProblemSetProgress.objects.filter(
|
if ProblemSetProgress.objects.filter(
|
||||||
|
|||||||
Reference in New Issue
Block a user