Basic AJAX requests and handlebars template for each review. Still static page #4
|
@ -0,0 +1 @@
|
|||
*.pyc
|
|
@ -106,14 +106,14 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
]
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'rest_framework.permissions.IsAuthenticated',
|
||||
),
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
),
|
||||
# 'DEFAULT_PERMISSION_CLASSES': (
|
||||
# 'rest_framework.permissions.IsAuthenticated',
|
||||
# ),
|
||||
# 'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
|
||||
# 'rest_framework.authentication.SessionAuthentication',
|
||||
# 'rest_framework.authentication.BasicAuthentication',
|
||||
# ),
|
||||
}
|
||||
|
||||
# Internationalization
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,49 @@
|
|||
from django.db import models
|
||||
|
||||
# Represents any object for which reviews can be made. (Universities, Professors, etc.)
|
||||
class RateableEntity(models.Model):
|
||||
# The human-readable name of this entity.
|
||||
name = models.CharField(max_length=256)
|
||||
|
||||
# A review represents any single data entry to the database.
|
||||
class Review(models.Model):
|
||||
# An integer rating in the domain [1, 5]
|
||||
rating = models.IntegerField(default=1)
|
||||
# A title for the review (brief summary of sentiment)
|
||||
title = models.CharField(max_length=128)
|
||||
# The textual content of the review.
|
||||
content = models.TextField()
|
||||
# A foreign key referencing the entity for which this review was made.
|
||||
rateable_entity = models.ForeignKey('postings.RateableEntity', on_delete=models.CASCADE)
|
||||
# The date and time at which this review was published.
|
||||
created_date = models.DateTimeField(auto_now_add=True)
|
||||
# The date and time at which the last modification to this review was published.
|
||||
last_updated_date = models.DateTimeField(auto_now=True)
|
||||
|
||||
# A vote for a review as either positive or negative.
|
||||
class ReviewHelpfulVote(models.Model):
|
||||
# A reference to the review that this vote is for.
|
||||
review = models.ForeignKey('postings.Review', on_delete=models.CASCADE)
|
||||
# Whether or not the referenced review was helpful.
|
||||
helpful = models.BooleanField()
|
||||
# TODO: Add a reference to the user who voted. The whole purpose of a separate vote object is to track who votes for what.
|
||||
|
||||
# A RateableEntity for universities.
|
||||
class University(RateableEntity):
|
||||
pass
|
||||
|
||||
# A RateableEntity for professors, who belong to one or more university.
|
||||
class Professor(RateableEntity):
|
||||
# The universities that this professor teaches or has taught at.
|
||||
university = models.ManyToManyField('postings.University')
|
||||
|
||||
# A RateableEntity for courses, which belong to a university, and have one or more professors.
|
||||
class Course(RateableEntity):
|
||||
# The university that this course belongs to.
|
||||
taught_at_university = models.ForeignKey('postings.University', on_delete=models.CASCADE)
|
||||
# A list of professors that teach this course.
|
||||
professors = models.ManyToManyField('postings.Professor')
|
||||
|
||||
# Create your models here.
|
||||
class UniversityReview(models.Model):
|
||||
university_name = models.CharField(max_length=200)
|
||||
|
|
|
@ -164,94 +164,9 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
<hr/>
|
||||
<div class="review-block">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<img src="http://dummyimage.com/60x60/666/ffffff&text=No+Image" class="img-rounded">
|
||||
<div class="review-block-name"><a href="#">Student</a></div>
|
||||
<div class="review-block-date">January 29, 2016<br/>1 day ago</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="review-block-rate">
|
||||
<div class="clearfix"></div>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="review-block-title">Course review 3</div>
|
||||
<div class="review-block-description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<img src="http://dummyimage.com/60x60/666/ffffff&text=No+Image" class="img-rounded">
|
||||
<div class="review-block-name"><a href="#">Student</a></div>
|
||||
<div class="review-block-date">January 29, 2016<br/>1 day ago</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="review-block-rate">
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="review-block-title">Course review 2</div>
|
||||
<div class="review-block-description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<img src="http://dummyimage.com/60x60/666/ffffff&text=No+Image" class="img-rounded">
|
||||
<div class="review-block-name"><a href="#">Student</a></div>
|
||||
<div class="review-block-date">January 29, 2016<br/>1 day ago</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="review-block-rate">
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="review-block-title">Course review 1</div>
|
||||
<div class="review-block-description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="review_container" class="review-block">
|
||||
<!-- All reviews go in this block. -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -262,10 +177,40 @@
|
|||
|
||||
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script>
|
||||
<script src="js/vendor/bootstrap.min.js"></script>
|
||||
<script src="js/vendor/handlebars-v4.0.12.js"></script>
|
||||
<!-- Handlebars templates -->
|
||||
<!-- TODO: Use a templating engine to automatically include all handlebars templates required for a certain page. -->
|
||||
<script id="review_item_handlebars" type="text/x-handlebars-template">
|
||||
<div class="row" id="{{pk}}">
|
||||
<div class="col-sm-3">
|
||||
<img src="http://dummyimage.com/60x60/666/ffffff&text=No+Image" class="img-rounded">
|
||||
<div class="review-block-name"><a href="#">{{username}}</a></div>
|
||||
<div class="review-block-date">
|
||||
{{date_published}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="review-block-rate">
|
||||
<span class="glyphicon glyphicon-star js_review_rating" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-star js_review_rating" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-star js_review_rating" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-star js_review_rating" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-star js_review_rating" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="review-block-title">
|
||||
{{title}}
|
||||
</div>
|
||||
<div class="review-block-description">
|
||||
{{content}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<!-- Custom scripts -->
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
<script src="js/load_reviews.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
var $ = jQuery;
|
||||
|
||||
// Load the handlebars template and use it to append all reviews.
|
||||
function displayReviews(reviews) {
|
||||
var template = Handlebars.compile($("#review_item_handlebars").html());
|
||||
var container = $("#review_container");
|
||||
reviews.forEach(function (review) {
|
||||
var review_html = template(review);
|
||||
container.append(review_html);
|
||||
// If a rating is defined, then hide only those rating stars which are higher than the current rating.
|
||||
// TODO: remove this check once this is added to the database.
|
||||
if (typeof(review.rating) !== "undefined") {
|
||||
$(".js_review_rating").each(function (index) {
|
||||
if ((index + 1) > review.rating) {
|
||||
this.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
container.append("<hr><br />");
|
||||
});
|
||||
}
|
||||
|
||||
function loadReviews () {
|
||||
$.ajax({
|
||||
url: "http://localhost:8000/api/postings/",
|
||||
method: "GET"
|
||||
}).done(function (response) {
|
||||
displayReviews(response);
|
||||
}).fail(function (response) {
|
||||
console.log("Could not get postings.");
|
||||
})
|
||||
}
|
||||
|
||||
loadReviews();
|
|
@ -0,0 +1,34 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<img src="http://dummyimage.com/60x60/666/ffffff&text=No+Image" class="img-rounded">
|
||||
<div class="review-block-name"><a href="#">{{username}}</a></div>
|
||||
<div class="review-block-date">
|
||||
{{date_published}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="review-block-rate">
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-grey btn-xs" aria-label="Left Align">
|
||||
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="review-block-title">
|
||||
{{title}}
|
||||
</div>
|
||||
<div class="review-block-description">
|
||||
{{content}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue