An actual minimum viable product, maybe? #11
|
@ -27,17 +27,11 @@ urlpatterns = [
|
||||||
# /reviews routes to the endpoint for POSTing new reviews.
|
# /reviews routes to the endpoint for POSTing new reviews.
|
||||||
path('reviews', views.post_review, name='post_review'),
|
path('reviews', views.post_review, name='post_review'),
|
||||||
|
|
||||||
# /universities routes to a list of universities.
|
# /rateables routes to a list of all rateable items: courses and universities.
|
||||||
path('universities', views.universities, name='universities_list'),
|
path('rateables', views.rateables, name='rateables'),
|
||||||
|
|
||||||
# /universities/<pk> routes to a specific university.
|
# /rateables/<pk> routes to a specific rateable entity.
|
||||||
path('universities/<int:university_id>', views.university_entity, name='university entity'),
|
path('rateables/<int:entity_id>', views.rateable_entity, name='rateable_entity'),
|
||||||
|
|
||||||
# /courses routes to a list of courses.
|
|
||||||
path('courses', views.courses, name='courses_list'),
|
|
||||||
|
|
||||||
# /courses/<pk> routes to a specific course.
|
|
||||||
path('courses/<int:course_id>', views.course_entity, name='course entity'),
|
|
||||||
|
|
||||||
# static files (*.css, *.js, *.jpg etc.) served on /
|
# static files (*.css, *.js, *.jpg etc.) served on /
|
||||||
# (assuming Django uses /static/ and /media/ for static/media urls)
|
# (assuming Django uses /static/ and /media/ for static/media urls)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
|
@ -1,11 +0,0 @@
|
||||||
{% extends "postings/collections/collection.html" %}
|
|
||||||
|
|
||||||
{# Represents a list of university entities. #}
|
|
||||||
|
|
||||||
{% block collection_name %}
|
|
||||||
<h2>Courses</h2>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block entity %}
|
|
||||||
<h3><a href="/courses/{{ entity.pk }}">{{ entity.name }}</a></h3>
|
|
||||||
{% endblock %}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{% extends "postings/collections/collection.html" %}
|
|
||||||
|
|
||||||
{# Represents a list of university entities. #}
|
|
||||||
|
|
||||||
{% block collection_name %}
|
|
||||||
<h2>Universities</h2>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block entity %}
|
|
||||||
<h3><a href="/universities/{{ entity.pk }}">{{ entity.name }}</a></h3>
|
|
||||||
{% endblock %}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{% extends "postings/entity_pages/entity.html" %}
|
|
||||||
|
|
||||||
{% block entity_info %}
|
|
||||||
Taught at: <a href="/universities/{{ entity.taught_at_university.pk }}">{{ entity.taught_at_university.name }}</a>
|
|
||||||
<h4>Professors</h4>
|
|
||||||
<ul>
|
|
||||||
{% for professor in entity.professors.all %}
|
|
||||||
<li>{{ professor.name }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endblock %}
|
|
|
@ -10,8 +10,8 @@
|
||||||
<button type="submit">Search</button>
|
<button type="submit">Search</button>
|
||||||
</form>
|
</form>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/universities">Universities</a>
|
<a href="/rateables?type=university">Universities</a>
|
||||||
<a href="/courses">Courses</a>
|
<a href="/rateables?type=course">Courses</a>
|
||||||
</nav>
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends "postings/rateables/entity.html" %}
|
||||||
|
|
||||||
|
{% block entity_info %}
|
||||||
|
Taught at: <a href="/rateables/{{ entity.taught_at_university.pk }}">{{ entity.taught_at_university.name }}</a>
|
||||||
|
<h4>Professors</h4>
|
||||||
|
<ul>
|
||||||
|
{% for professor in entity.professors.all %}
|
||||||
|
<li>{{ professor.name }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
|
@ -10,9 +10,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% for entity in entities %}
|
{% for entity in entities %}
|
||||||
<li>
|
<li>
|
||||||
{% block entity %}
|
<a href="/rateables/{{ entity.pk }}">{{ entity.name }}</a>
|
||||||
{{ entity.name }}
|
|
||||||
{% endblock %}
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
|
@ -4,9 +4,10 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h2>Name: {{ entity.name }}</h2> Average rating: {{ entity.average_rating|floatformat:"-2" }}
|
<h2>Name: {{ entity.name }} {{ entity.average }}</h2>
|
||||||
|
<h3>Average rating: {{ entity.average_rating|floatformat:"-2" }}</h3>
|
||||||
|
|
||||||
{# Child templates can redefine this block for displaying data pertaining to that specific entity. #}
|
{# Depending on the type of entity, some detailed info is provided here. #}
|
||||||
{% block entity_info %}
|
{% block entity_info %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -16,8 +17,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% for review in entity.review_set.all %}
|
{% for review in entity.review_set.all %}
|
||||||
<li>
|
<li>
|
||||||
<h4>{{ review.title }}</h4> {{ review.rating }}
|
{% include "postings/rateables/review.html" with review=review only %}
|
||||||
<p>{{ review.content }}
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
|
@ -0,0 +1,7 @@
|
||||||
|
{# Template for displaying one review. #}
|
||||||
|
|
||||||
|
<h4>{{ review.title }}</h4>
|
||||||
|
<i>Rating: {{ review.rating }}</i><br>
|
||||||
|
<i>Posted on {{ review.created_date|date:"j M, Y" }}</i><br>
|
||||||
|
|
||||||
|
<p>{{ review.content }}</p>
|
|
@ -1,10 +1,10 @@
|
||||||
{% extends "postings/entity_pages/entity.html" %}
|
{% extends "postings/rateables/entity.html" %}
|
||||||
|
|
||||||
{% block entity_info %}
|
{% block entity_info %}
|
||||||
<h4>Courses</h4>
|
<h4>Courses</h4>
|
||||||
<ul>
|
<ul>
|
||||||
{% for course in entity.course_set.all %}
|
{% for course in entity.course_set.all %}
|
||||||
<li><a href="/courses/{{ course.pk }}">{{ course.name }}</a></li>
|
<li><a href="/rateables/{{ course.pk }}">{{ course.name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<h4>Professors</h4>
|
<h4>Professors</h4>
|
|
@ -11,38 +11,43 @@ def index(request):
|
||||||
search_query = request.GET.get('search_query', None)
|
search_query = request.GET.get('search_query', None)
|
||||||
results = None
|
results = None
|
||||||
if search_query:
|
if search_query:
|
||||||
|
# Filter objects based on case-insensitive contains filter.
|
||||||
results = RateableEntity.objects.filter(name__icontains=search_query)
|
results = RateableEntity.objects.filter(name__icontains=search_query)
|
||||||
|
|
||||||
return render(request, 'postings/index.html', {'results': results})
|
return render(request, 'postings/index.html', {'results': results})
|
||||||
|
|
||||||
# The view for a listing of universities.
|
# The view for listing all rateable entities.
|
||||||
def universities(request):
|
def rateables(request):
|
||||||
universities_list = University.objects.all()
|
entity_type = request.GET.get('type', None)
|
||||||
context = {'entities': universities_list}
|
entities = None
|
||||||
return render(request, 'postings/collections/universities.html', context)
|
if entity_type == "university":
|
||||||
|
entities = University.objects.all()
|
||||||
|
elif entity_type == "course":
|
||||||
|
entities = Course.objects.all()
|
||||||
|
else:
|
||||||
|
entities = RateableEntity.objects.all()
|
||||||
|
return render(request, "postings/rateables/entities.html", {'entities': entities})
|
||||||
|
|
||||||
# The view for /universities/<pk> Displays one university entity.
|
# The view for any rateable entity.
|
||||||
def university_entity(request, university_id):
|
def rateable_entity(request, entity_id):
|
||||||
try:
|
try:
|
||||||
university = University.objects.get(pk=university_id)
|
entity = RateableEntity.objects.get(pk=entity_id)
|
||||||
university.average_rating = university.getAverageRating()
|
|
||||||
except University.DoesNotExist:
|
|
||||||
raise Http404("University does not exist")
|
|
||||||
return render(request, 'postings/entity_pages/university.html', {'entity': university})
|
|
||||||
|
|
||||||
# The view for a listing of courses.
|
# Try and get a more specific entity type from what is provided.
|
||||||
def courses(request):
|
if entity.entity_type == RateableEntity.UNIVERSITY:
|
||||||
courses_list = Course.objects.all()
|
entity = University.objects.get(pk=entity.pk)
|
||||||
context = {'entities': courses_list}
|
template = "university.html"
|
||||||
return render(request, 'postings/collections/courses.html', context)
|
elif entity.entity_type == RateableEntity.COURSE:
|
||||||
|
entity = Course.objects.get(pk=entity.pk)
|
||||||
|
template = "course.html"
|
||||||
|
|
||||||
# The view for a specific course entity.
|
# Set any auxiliary variables needed, like average rating.
|
||||||
def course_entity(request, course_id):
|
# This MUST be done after categorizing the object above.
|
||||||
try:
|
entity.average_rating = entity.getAverageRating()
|
||||||
course = Course.objects.get(pk=course_id)
|
|
||||||
except Course.DoesNotExist:
|
except RateableEntity.DoesNotExist:
|
||||||
raise Http404("Course does not exist")
|
raise Http404("RateableEntity with id " + str(entity_id) + " does not exist.")
|
||||||
return render(request, 'postings/entity_pages/course.html', {'entity': course})
|
return render(request, "postings/rateables/" + template, {'entity': entity})
|
||||||
|
|
||||||
# The view for receiving POST requests for new reviews.
|
# The view for receiving POST requests for new reviews.
|
||||||
def post_review(request):
|
def post_review(request):
|
||||||
|
@ -54,7 +59,10 @@ def post_review(request):
|
||||||
title = form.cleaned_data['title']
|
title = form.cleaned_data['title']
|
||||||
content = form.cleaned_data['content']
|
content = form.cleaned_data['content']
|
||||||
entity_id = form.cleaned_data['entity_id']
|
entity_id = form.cleaned_data['entity_id']
|
||||||
entity = RateableEntity.objects.get(pk=entity_id)
|
try:
|
||||||
|
entity = RateableEntity.objects.get(pk=entity_id)
|
||||||
|
except RateableEntity.DoesNotExist:
|
||||||
|
raise HttpResponseBadRequest("Bad Request: Invalid entity id.")
|
||||||
|
|
||||||
# Creates the new Review object from the posted data.
|
# Creates the new Review object from the posted data.
|
||||||
review = Review.objects.create(
|
review = Review.objects.create(
|
||||||
|
@ -65,11 +73,6 @@ def post_review(request):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Send the user back to the entity they were viewing.
|
# Send the user back to the entity they were viewing.
|
||||||
redirect_path = '/'
|
return HttpResponseRedirect('/rateables/' + str(entity_id))
|
||||||
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")
|
return HttpResponseBadRequest("Bad Request")
|
Loading…
Reference in New Issue