This commit is contained in:
2026-08-06 08:36:01 -06:00
parent 3a99c6a890
commit 5586c9b573
3 changed files with 4 additions and 47 deletions

View File

@@ -4,23 +4,4 @@ from utils.api import serializers
class SetReactionSerializer(serializers.Serializer): class SetReactionSerializer(serializers.Serializer):
problem_id = serializers.IntegerField() problem_id = serializers.IntegerField()
type = serializers.ChoiceField(choices=ReactionType.choices, required=False) type = serializers.ChoiceField(choices=ReactionType.choices)
types = serializers.ListField(
child=serializers.ChoiceField(choices=ReactionType.choices),
required=False,
allow_empty=False,
)
def validate(self, attrs):
reaction_type = attrs.get("type")
legacy_types = list(dict.fromkeys(attrs.get("types", [])))
if len(legacy_types) > 1:
raise serializers.ValidationError({"types": "只能选择一个评价"})
if reaction_type is None and not legacy_types:
raise serializers.ValidationError({"type": "This field is required."})
if reaction_type is not None and legacy_types and reaction_type != legacy_types[0]:
raise serializers.ValidationError({"types": "新旧评价字段不一致"})
attrs["type"] = reaction_type or legacy_types[0]
return attrs

View File

@@ -11,29 +11,6 @@ class SetReactionSerializerTests(TestCase):
self.assertTrue(serializer.is_valid(), serializer.errors) self.assertTrue(serializer.is_valid(), serializer.errors)
self.assertEqual(serializer.validated_data["type"], "learned") self.assertEqual(serializer.validated_data["type"], "learned")
def test_accepts_legacy_single_reaction(self):
serializer = SetReactionSerializer(data={"problem_id": 1, "types": ["learned"]})
self.assertTrue(serializer.is_valid(), serializer.errors)
self.assertEqual(serializer.validated_data["type"], "learned")
def test_accepts_matching_transition_fields(self):
serializer = SetReactionSerializer(data={"problem_id": 1, "type": "learned", "types": ["learned"]})
self.assertTrue(serializer.is_valid(), serializer.errors)
def test_rejects_multiple_legacy_reactions(self):
serializer = SetReactionSerializer(data={"problem_id": 1, "types": ["learned", "interesting"]})
self.assertFalse(serializer.is_valid())
self.assertIn("types", serializer.errors)
def test_rejects_mismatched_transition_fields(self):
serializer = SetReactionSerializer(data={"problem_id": 1, "type": "learned", "types": ["interesting"]})
self.assertFalse(serializer.is_valid())
self.assertIn("types", serializer.errors)
def test_rejects_missing_reaction(self): def test_rejects_missing_reaction(self):
serializer = SetReactionSerializer(data={"problem_id": 1}) serializer = SetReactionSerializer(data={"problem_id": 1})
@@ -53,4 +30,3 @@ class ReactionModelConstraintTests(TestCase):
constraint = constraints["reaction_problem_user_unique"] constraint = constraints["reaction_problem_user_unique"]
self.assertEqual(tuple(constraint.fields), ("problem", "user")) self.assertEqual(tuple(constraint.fields), ("problem", "user"))
self.assertEqual(Reaction._meta.unique_together, ())

View File

@@ -23,8 +23,8 @@ class ReactionAPI(AsyncAPIView):
return self.error("problem_id is required") return self.error("problem_id is required")
mine = await Reaction.objects.filter(user=request.user, problem_id=problem_id).values_list("type", flat=True).afirst() mine = await Reaction.objects.filter(user=request.user, problem_id=problem_id).values_list("type", flat=True).afirst()
if mine is None: if mine is None:
return self.success({"mine": [], "mine_type": None, "counts": None}) return self.success({"mine": None, "counts": None})
return self.success({"mine": [mine], "mine_type": mine, "counts": await self.get_counts(problem_id)}) return self.success({"mine": mine, "counts": await self.get_counts(problem_id)})
@login_required @login_required
@validate_serializer(SetReactionSerializer) @validate_serializer(SetReactionSerializer)
@@ -54,4 +54,4 @@ class ReactionAPI(AsyncAPIView):
defaults={"type": reaction_type}, defaults={"type": reaction_type},
) )
return self.success({"mine": [reaction.type], "mine_type": reaction.type, "counts": await self.get_counts(problem.id)}) return self.success({"mine": reaction.type, "counts": await self.get_counts(problem.id)})