fix
This commit is contained in:
@@ -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
|
|
||||||
|
|||||||
@@ -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, ())
|
|
||||||
|
|||||||
@@ -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)})
|
||||||
|
|||||||
Reference in New Issue
Block a user