diff --git a/backend/RateMyCourse/urls.py b/backend/RateMyCourse/urls.py index cc3e5cb..00a147e 100644 --- a/backend/RateMyCourse/urls.py +++ b/backend/RateMyCourse/urls.py @@ -24,6 +24,9 @@ urlpatterns = [ # / routes to index.html path('', views.index, name='homepage'), + # /reviews routes to the endpoint for POSTing new reviews. + path('reviews', views.post_review, name='post_review'), + # /universities routes to a list of universities. path('universities', views.universities, name='universities_list'), diff --git a/backend/db.sqlite3 b/backend/db.sqlite3 index ae677ce..823e972 100644 Binary files a/backend/db.sqlite3 and b/backend/db.sqlite3 differ diff --git a/backend/postings/forms.py b/backend/postings/forms.py new file mode 100644 index 0000000..99d8065 --- /dev/null +++ b/backend/postings/forms.py @@ -0,0 +1,12 @@ +from django import forms + +# The form for creating a review for any sort of rateable entity. +class EntityReviewForm(forms.Form): + # The integer rating from 1 to 5. + rating = forms.IntegerField(min_value=1, max_value=5) + # The title of the review. + title = forms.CharField(max_length=128) + # The textual content of the review. + content = forms.CharField(widget=forms.Textarea) + # The id of the entity for which the review is created. + entity_id = forms.IntegerField() \ No newline at end of file diff --git a/backend/postings/models.py b/backend/postings/models.py index ce3fb64..d998984 100644 --- a/backend/postings/models.py +++ b/backend/postings/models.py @@ -36,6 +36,8 @@ class RateableEntity(models.Model): rating_sum = 0 for review in reviews: rating_sum += review.rating + if reviews.count() == 0: + return None return rating_sum / reviews.count() # Simply returns the name as the string representation. diff --git a/backend/postings/templates/postings/entity_pages/entity.html b/backend/postings/templates/postings/entity_pages/entity.html index 24d220b..49aa6ff 100644 --- a/backend/postings/templates/postings/entity_pages/entity.html +++ b/backend/postings/templates/postings/entity_pages/entity.html @@ -4,11 +4,13 @@ {% block content %} -

Name: {{ entity.name }}

Average rating: {{ entity.average_rating }} +

Name: {{ entity.name }}

Average rating: {{ entity.average_rating|floatformat:"-2" }} +{# Child templates can redefine this block for displaying data pertaining to that specific entity. #} {% block entity_info %} {% endblock %} +{# This section displays all reviews for a given entity. #}

Reviews

+{# This section is where the user can write a review for a particular entity and submit it. #} +
+

Write a Review

+
+ + +
+ + + +
+ + + +
+ + {# The following csrf_token and input fields are hidden values needed for form submission. #} + {% csrf_token %} + + + +
+
+ {% endblock %} \ No newline at end of file diff --git a/backend/postings/views.py b/backend/postings/views.py index d8ae6df..4eb60cb 100644 --- a/backend/postings/views.py +++ b/backend/postings/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render -from django.http import HttpResponse, Http404 +from django.http import HttpResponse, Http404, HttpResponseBadRequest, HttpResponseRedirect from postings.models import * +from postings.forms import * # Create your views here. @@ -41,4 +42,34 @@ def course_entity(request, course_id): course = Course.objects.get(pk=course_id) except Course.DoesNotExist: raise Http404("Course does not exist") - return render(request, 'postings/entity_pages/course.html', {'entity': course}) \ No newline at end of file + return render(request, 'postings/entity_pages/course.html', {'entity': course}) + +# The view for receiving POST requests for new reviews. +def post_review(request): + if request.method == 'POST': + form = EntityReviewForm(request.POST) + if form.is_valid(): + # Only if the request is a POST and the form is valid do we do anything. + rating = form.cleaned_data['rating'] + title = form.cleaned_data['title'] + content = form.cleaned_data['content'] + entity_id = form.cleaned_data['entity_id'] + entity = RateableEntity.objects.get(pk=entity_id) + + # Creates the new Review object from the posted data. + review = Review.objects.create( + rating=rating, + title=title, + content=content, + rateable_entity=entity + ) + + # Send the user back to the entity they were viewing. + redirect_path = '/' + if entity.entity_type == RateableEntity.UNIVERSITY: + redirect_path = '/universities/' + str(entity_id) + elif entity.entity_type == RateableEntity.COURSE: + redirect_path = '/courses/' + str(entity_id) + return HttpResponseRedirect(redirect_path) + + return HttpResponseBadRequest("Bad Request") \ No newline at end of file