Skip to content

Commit

Permalink
Revert "Merge branch 'ta-reviews' into ta-reviews_frontend"
Browse files Browse the repository at this point in the history
This reverts commit 8aa3c2f, reversing
changes made to 98c52fb.
  • Loading branch information
benjmnxu committed Mar 28, 2024
1 parent 8aa3c2f commit 08bb439
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 617 deletions.
5 changes: 1 addition & 4 deletions backend/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ gunicorn = "*"
django-scheduler = "*"
typing-extensions = "*"
drf-excel = "*"
django-extensions = "*"
django-debug-toolbar = "*"
parameterized = "*"

[requires]
python_version = "3.10.8"
python_version = "3"
31 changes: 0 additions & 31 deletions backend/ohq/migrations/0020_auto_20221106_1919.py

This file was deleted.

18 changes: 0 additions & 18 deletions backend/ohq/migrations/0021_auto_20221110_1803.py

This file was deleted.

19 changes: 0 additions & 19 deletions backend/ohq/migrations/0022_auto_20221111_0135.py

This file was deleted.

29 changes: 0 additions & 29 deletions backend/ohq/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,26 +240,6 @@ class Meta:
def __str__(self):
return f"{self.course}: {self.name}"

class Review(models.Model):
"""
TA reviews within a question
"""
RATING_ONE = 1
RATING_TWO = 2
RATING_THREE = 3
RATING_FOUR = 4
RATING_FIVE = 5
RATING_CHOICES = [
(RATING_ONE, "One star"),
(RATING_TWO, "Two stars"),
(RATING_THREE, "Three stars"),
(RATING_FOUR, "Four stars"),
(RATING_FIVE, "Five stars")
]

content = models.TextField(blank=True)
rating = models.IntegerField(choices=RATING_CHOICES)


class Question(models.Model):
"""
Expand Down Expand Up @@ -302,14 +282,6 @@ class Question(models.Model):
should_send_up_soon_notification = models.BooleanField(default=False)
tags = models.ManyToManyField(Tag, blank=True)
student_descriptor = models.CharField(max_length=255, blank=True, null=True)
review = models.OneToOneField(Review, on_delete=models.CASCADE, blank=True, null=True)

class Meta:
constraints = [
models.UniqueConstraint(
fields=["review"], name="unique_question"
)
]


class CourseStatistic(models.Model):
Expand Down Expand Up @@ -453,4 +425,3 @@ class Review(models.Model):
question = models.OneToOneField(Question, related_name="reviews",
on_delete=models.CASCADE, primary_key=True, blank=True, null=False)
time_updated = models.DateTimeField(auto_now=True)

25 changes: 17 additions & 8 deletions backend/ohq/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,22 +504,31 @@ def has_permission(self, request, view):

return True


class ReviewPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
membership = Membership.objects.get(course=view.kwargs["course_pk"], user=request.user)
question = Question.objects.get(pk=view.kwargs["question_pk"])

# Students can get or modify their own review
# Only Head TAs and Professors can get or modify any questions
if view.action in ["retrieve"]:
return question.asked_by == request.user or membership.is_leadership

if view.action in ["update", "partial_update"]:
return question.asked_by == request.user

def has_permission(self, request, view):
# Anonymous users can't do anything
if not request.user.is_authenticated:
return False

membership = Membership.objects.filter(
course=view.kwargs["course_pk"], user=request.user
).first()

# Non-Students can't do anything
if membership is None:
return False

# Only students can create, modify and delete reviews
if view.action in ["create", "update", "partial_update", "destroy"]:

if view.action == "create":
return (not membership.is_ta) and (not membership.is_leadership)

return True
58 changes: 0 additions & 58 deletions backend/ohq/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from django.core.exceptions import ObjectDoesNotExist
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.http import JsonResponse
from phonenumber_field.serializerfields import PhoneNumberField
from rest_framework import serializers
from rest_live.signals import save_handler
Expand Down Expand Up @@ -52,41 +51,6 @@ def save(self):
self.validated_data["queue"] = Queue.objects.get(pk=self.context["view"].kwargs["queue_pk"])
return super().save()

class QuestionReviewRouteMixin(serializers.ModelSerializer):
"""
Mixin for serializers that overrides the save method to
properly handle the URL parameter for questions.
"""

def save(self):
self.validated_data["question"] = Question.objects.get(pk=self.context["view"].kwargs["question_pk"])

if self.validated_data["question"].status != "ANSWERED":
return JsonResponse({"detail": "This question has not been answered by a TA yet"})

if self.context["request"].method == "POST" and "rating" in self.validated_data:
if "rating" not in self.validated_data:
return JsonResponse({"detail": "A rating must be provided"})
if self.validated_data["question"].review != None:
return JsonResponse({"detail": "This question is already reviewed."})
review = Review(content="", rating=self.validated_data["rating"])
if "content" in self.validated_data:
review.content = self.validated_data["content"]
review.save()
self.validated_data["question"].review = review
self.validated_data["question"].save()
return JsonResponse({"detail": "Your review has been posted."})

if self.context["request"].method == "PATCH":
self.validated_data["review"] = Review.objects.get(pk=self.context["view"].kwargs["pk"])
if "rating" not in self.validated_data and "content" not in self.validated_data:
return JsonResponse({"detail": "Your review does not contain any content or rating."})
if "rating" in self.validated_data:
self.validated_data["review"].rating = self.validated_data["rating"]
if "content" in self.validated_data:
self.validated_data["review"].content = self.validated_data["content"]
self.validated_data["review"].save()
return JsonResponse({"detail": "Your review is updated"})

class SemesterSerializer(serializers.ModelSerializer):
pretty = serializers.SerializerMethodField()
Expand Down Expand Up @@ -246,26 +210,11 @@ class Meta:
fields = ("id", "name")


class ReviewSerializer(QuestionReviewRouteMixin):
"""
Serializer for review
"""
question = serializers.ReadOnlyField(source="question.text")
ta_first_name = serializers.ReadOnlyField(source="question.responded_to_by.first_name")
ta_last_name = serializers.ReadOnlyField(source="question.responded_to_by.last_name")

class Meta:
model = Review
fields = ("id", "content", "rating", "question", "ta_first_name", "ta_last_name")
read_only_fields = ("question", "ta_first_name", "ta_last_name")


class QuestionSerializer(QueueRouteMixin):
asked_by = UserSerializer(read_only=True)
responded_to_by = UserSerializer(read_only=True)
tags = TagSerializer(many=True)
position = serializers.IntegerField(default=-1, read_only=True)
review = ReviewSerializer(read_only=True)

class Meta:
model = Question
Expand All @@ -286,7 +235,6 @@ class Meta:
"resolved_note",
"position",
"student_descriptor",
"review",
)
read_only_fields = (
"time_asked",
Expand All @@ -297,7 +245,6 @@ class Meta:
"should_send_up_soon_notification",
"resolved_note",
"position",
"review",
)

def update(self, instance, validated_data):
Expand Down Expand Up @@ -396,11 +343,6 @@ def create(self, validated_data):
except ObjectDoesNotExist:
continue
return question

def get_review(self, obj):
review = Review.objects.get(question=obj)
serializer = ReviewSerializer(review)
return serializer.data


class MembershipPrivateSerializer(CourseRouteMixin):
Expand Down
57 changes: 3 additions & 54 deletions backend/ohq/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,27 +180,6 @@ def get_queryset(self):
)
return prefetch(qs, self.get_serializer_class())

@action(detail=True)
def reviews(self, request, pk):
membership = Membership.objects.get(course=pk, user=self.request.user)

if membership.kind == "PROFESSOR" or membership.kind_to_pretty == "HEAD_TA" or self.request.user.is_superuser:
questions = Question.objects.select_related("review").filter(queue__in=Queue.objects.filter(course=pk))

elif membership.kind == "TA":
questions = Question.objects.select_related("review").filter(queue__in=Queue.objects.filter(course=pk), responded_to_by=self.request.user)

elif membership.kind == "STUDENT":
questions = Question.objects.select_related("review").filter(queue__in=Queue.objects.filter(course=pk), asked_by=self.request.user)

reviews = []
serializer = ReviewSerializer(many=True)
for question in questions:
reviews.append(question.review)
serializer = ReviewSerializer(reviews, many=True)
return JsonResponse(serializer.data, safe=False)



class QuestionViewSet(viewsets.ModelViewSet, RealtimeMixin):
"""
Expand Down Expand Up @@ -799,41 +778,11 @@ def list(self, request, *args, **kwargs):
def get_queryset(self):
return Occurrence.objects.filter(pk=self.kwargs["pk"])

class ReviewViewSet(viewsets.ModelViewSet):
"""
retrieve:
Return a review based on type of user. All reviews are anonymous.
Students can retrieve review made by themselves.
TAs can retrieve reviews made for themselves.
Head TAs/Professor can retrieve any review.
list:
Return a list of reviews based on type of user. All reviews are anonymous.
Students can retrieve reviews made by themselves.
TAs can retrieve reviews made for themselves.
Head TAs/Professor can retrieve anyreview.
update:
Update all fields in a review.
You must specify all of the fields or use a patch request.
partial_update:
Update certain fields in a review.
Only specify the fields that you want to change.

destroy:
Delete a review.
reviewId is required.
"""
class ReviewViewSet(viewsets.ModelViewSet):
# permission_classes = [ReviewPermission | IsSuperuser]
serializer_class = ReviewSerializer
permission_classes = [ReviewPermission | IsSuperuser]
queryset = Review.objects.none()

def get_queryset(self):
membership = Membership.objects.get(course=self.kwargs["course_pk"], user=self.request.user)
if membership.kind == "TA":
return Review.objects.filter(question=self.kwargs["question_pk"], question__responded_to_by=self.request.user)

if membership.kind == "STUDENT":
return Review.objects.filter(question=self.kwargs["question_pk"], question__asked_by=self.request.user)

return Review.objects.filter(question=self.kwargs["question_pk"])
Loading

0 comments on commit 08bb439

Please sign in to comment.