From 1492d2f5e761de2d7d43e0ca44d7a83edc690a3b Mon Sep 17 00:00:00 2001 From: Dominik Seeger <dominik.seeger@stud.uni-goettingen.de> Date: Tue, 9 Jul 2019 18:32:24 +0200 Subject: [PATCH 1/5] added dedicated field for reviewer validation --- core/migrations/0018_auto_20190709_1526.py | 23 ++++++++++++++++++++++ core/models/feedback.py | 3 +++ core/views/feedback.py | 15 +++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 core/migrations/0018_auto_20190709_1526.py diff --git a/core/migrations/0018_auto_20190709_1526.py b/core/migrations/0018_auto_20190709_1526.py new file mode 100644 index 00000000..468d2442 --- /dev/null +++ b/core/migrations/0018_auto_20190709_1526.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2 on 2019-07-09 15:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0017_auto_20190604_1631'), + ] + + operations = [ + migrations.AddField( + model_name='feedback', + name='final_by_reviewer', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='feedbacklabel', + name='name', + field=models.CharField(max_length=50, unique=True), + ), + ] diff --git a/core/models/feedback.py b/core/models/feedback.py index 15eea22c..742f9428 100644 --- a/core/models/feedback.py +++ b/core/models/feedback.py @@ -25,10 +25,13 @@ class Feedback(models.Model): points a student receives for his submission. origin : IntegerField Of whom was this feedback originally created. She below for the choices + final_by_reviewer: BooleanField + Whether or not this feedback was set to final by a reviewer once """ score = models.DecimalField(max_digits=5, decimal_places=2, default=0) created = models.DateTimeField(auto_now_add=True) is_final = models.BooleanField(default=False) + final_by_reviewer = models.BooleanField(default=False) of_submission = models.OneToOneField( Submission, diff --git a/core/views/feedback.py b/core/views/feedback.py index 27211eb7..113e1cc8 100644 --- a/core/views/feedback.py +++ b/core/views/feedback.py @@ -28,12 +28,13 @@ class FeedbackApiView( lookup_url_kwarg = 'submission_pk' def _tutor_attempts_to_change_final_feedback_of_reviewer(self, serializer): - feedback_is_final = serializer.instance.is_final + feedback_final_by_reviewer = serializer.instance.final_by_reviewer user_is_tutor = self.request.user.role == models.UserAccount.TUTOR - authors = serializer.instance.of_submission.meta.feedback_authors - set_by_reviewer = authors.filter( - role=models.UserAccount.REVIEWER).exists() - return feedback_is_final and set_by_reviewer and user_is_tutor + return feedback_final_by_reviewer and user_is_tutor + + def _set_final_by_reviewer(self, serializer): + feedback_final_by_reviewer = serializer.validated_data.get('is_final', True) + serializer.save(final_by_reviewer=feedback_final_by_reviewer) def _get_implicit_assignment_for_user(self, submission): """ Check for tutor if it exists. Not relevant for reviewer """ @@ -96,6 +97,8 @@ class FeedbackApiView( {'For tutors it is not allowed to create feedback final.'}, status=status.HTTP_403_FORBIDDEN) + self._set_final_by_reviewer(serializer) + self.perform_create(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -116,6 +119,8 @@ class FeedbackApiView( raise PermissionDenied( detail='Cannot set the first feedback final.') + self._set_final_by_reviewer(serializer) + serializer.save() return Response(serializer.data) -- GitLab From d45a5898882f22f24305b82deffe1b0ba0950334 Mon Sep 17 00:00:00 2001 From: Dominik Seeger <dominik.seeger@gmx.net> Date: Tue, 6 Aug 2019 15:23:28 +0200 Subject: [PATCH 2/5] put the final by reviewer logic in the serializer --- core/serializers/feedback.py | 11 ++++++++++- core/views/feedback.py | 8 -------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py index 92416e1e..5a6749ec 100644 --- a/core/serializers/feedback.py +++ b/core/serializers/feedback.py @@ -7,7 +7,7 @@ from rest_framework import serializers from rest_framework.utils import html from core import models -from core.models import Feedback +from core.models import Feedback, UserAccount from util.factories import GradyUserFactory from .generic import DynamicFieldsModelSerializer @@ -121,8 +121,12 @@ class FeedbackSerializer(DynamicFieldsModelSerializer): submission = validated_data.pop('of_submission') feedback_lines = validated_data.pop('feedback_lines', []) labels = validated_data.pop('labels', []) + user = UserAccount.objects.get(username=str(self.context['request'].user)) feedback = Feedback.objects.create(of_submission=submission, **validated_data) + if user.role == UserAccount.REVIEWER: + feedback.final_by_reviewer = self.context['request'].data['is_final'] + for label in labels: feedback.labels.add(label) @@ -141,6 +145,11 @@ class FeedbackSerializer(DynamicFieldsModelSerializer): @transaction.atomic def update(self, feedback, validated_data): + user = UserAccount.objects.get(username=str(self.context['request'].user)) + + if user.role == UserAccount.REVIEWER: + feedback.final_by_reviewer = self.context['request'].data['is_final'] + for comment in validated_data.pop('feedback_lines', []): labels = comment.pop('labels', []) comment_instance, _ = models.FeedbackComment.objects.update_or_create( diff --git a/core/views/feedback.py b/core/views/feedback.py index 113e1cc8..e7ccfb22 100644 --- a/core/views/feedback.py +++ b/core/views/feedback.py @@ -32,10 +32,6 @@ class FeedbackApiView( user_is_tutor = self.request.user.role == models.UserAccount.TUTOR return feedback_final_by_reviewer and user_is_tutor - def _set_final_by_reviewer(self, serializer): - feedback_final_by_reviewer = serializer.validated_data.get('is_final', True) - serializer.save(final_by_reviewer=feedback_final_by_reviewer) - def _get_implicit_assignment_for_user(self, submission): """ Check for tutor if it exists. Not relevant for reviewer """ try: @@ -97,8 +93,6 @@ class FeedbackApiView( {'For tutors it is not allowed to create feedback final.'}, status=status.HTTP_403_FORBIDDEN) - self._set_final_by_reviewer(serializer) - self.perform_create(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -119,8 +113,6 @@ class FeedbackApiView( raise PermissionDenied( detail='Cannot set the first feedback final.') - self._set_final_by_reviewer(serializer) - serializer.save() return Response(serializer.data) -- GitLab From a18c5292b8d61163db2f73f83d2da7f4476c0d70 Mon Sep 17 00:00:00 2001 From: "dominik.seeger" <dominik.seeger@stud.uni-goettingen.de> Date: Fri, 9 Aug 2019 13:03:04 +0200 Subject: [PATCH 3/5] Apply suggestion to core/serializers/feedback.py --- core/serializers/feedback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py index 5a6749ec..d8316e66 100644 --- a/core/serializers/feedback.py +++ b/core/serializers/feedback.py @@ -145,7 +145,7 @@ class FeedbackSerializer(DynamicFieldsModelSerializer): @transaction.atomic def update(self, feedback, validated_data): - user = UserAccount.objects.get(username=str(self.context['request'].user)) +user = self.context['request'].user if user.role == UserAccount.REVIEWER: feedback.final_by_reviewer = self.context['request'].data['is_final'] -- GitLab From 4f78a5550eb2d5c54c05853319282e4b62c09dab Mon Sep 17 00:00:00 2001 From: "dominik.seeger" <dominik.seeger@stud.uni-goettingen.de> Date: Fri, 9 Aug 2019 13:03:25 +0200 Subject: [PATCH 4/5] Apply suggestion to core/serializers/feedback.py --- core/serializers/feedback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py index d8316e66..32ed137f 100644 --- a/core/serializers/feedback.py +++ b/core/serializers/feedback.py @@ -121,7 +121,7 @@ class FeedbackSerializer(DynamicFieldsModelSerializer): submission = validated_data.pop('of_submission') feedback_lines = validated_data.pop('feedback_lines', []) labels = validated_data.pop('labels', []) - user = UserAccount.objects.get(username=str(self.context['request'].user)) + user = self.context['request'].user feedback = Feedback.objects.create(of_submission=submission, **validated_data) if user.role == UserAccount.REVIEWER: -- GitLab From 6191b7855bec05a648eef90e3ab7e19d03388e09 Mon Sep 17 00:00:00 2001 From: Dominik Seeger <dominik.seeger@gmx.net> Date: Wed, 14 Aug 2019 12:21:47 +0200 Subject: [PATCH 5/5] fixed indentation --- core/serializers/feedback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py index 32ed137f..da0d45e5 100644 --- a/core/serializers/feedback.py +++ b/core/serializers/feedback.py @@ -145,7 +145,7 @@ class FeedbackSerializer(DynamicFieldsModelSerializer): @transaction.atomic def update(self, feedback, validated_data): -user = self.context['request'].user + user = self.context['request'].user if user.role == UserAccount.REVIEWER: feedback.final_by_reviewer = self.context['request'].data['is_final'] -- GitLab