Commit 6d7d4fd8 by Stephen Sanchez

Ensuring the right many to many relationship is preserved for Assessment Feedback

parent 16c1f57f
......@@ -376,7 +376,7 @@ class AssessmentPart(models.Model):
class AssessmentFeedback(models.Model):
"""A response to a submission's feedback, judging accuracy or helpfulness."""
submission_uuid = models.CharField(max_length=128, unique=True, db_index=True)
assessments = models.ManyToManyField(Assessment, related_name='assessment_feedback')
assessments = models.ManyToManyField(Assessment, related_name='assessment_feedback', default=None)
HELPFULNESS_CHOICES = (
(0, 'These results were not at all helpful'),
(1, 'These results were somewhat helpful'),
......
......@@ -907,10 +907,12 @@ def get_assessment_feedback(submission_uuid):
"""
try:
feedback, feedback_created = AssessmentFeedback.objects.get_or_create(
feedback = AssessmentFeedback.objects.get(
submission_uuid=submission_uuid
)
return AssessmentFeedbackSerializer(feedback).data
except AssessmentFeedback.DoesNotExist:
return None
except DatabaseError:
error_message = (
u"An error occurred retrieving assessment feedback for {}."
......@@ -934,15 +936,13 @@ def set_assessment_feedback(must_grade, feedback_dict):
Returns:
The modified or created feedback.
"""
submission_uuid = feedback_dict.get('submission_uuid', '')
submission_uuid = feedback_dict.get('submission_uuid')
if not submission_uuid:
error_message = u"An error occurred creating assessment feedback: bad or missing submission_uuid."
logger.exception(error_message)
raise PeerAssessmentInternalError(error_message)
logger.error(error_message)
raise PeerAssessmentRequestError(error_message)
try:
feedback_model = AssessmentFeedback.objects.get_or_create(submission_uuid=submission_uuid)
submission = Submission.objects.get(uuid=submission_uuid)
assessments = Assessment.objects.filter(submission=submission, score_type="PE")
assessments = Assessment.objects.filter(submission__uuid=submission_uuid, score_type="PE")
except DatabaseError:
error_message = (
u"An error occurred getting database state to set assessment feedback for {}."
......@@ -950,12 +950,16 @@ def set_assessment_feedback(must_grade, feedback_dict):
)
logger.exception(error_message)
raise PeerAssessmentInternalError(error_message)
feedback_dict['assessments'] = [ assessment.pk for assessment in assessments[:must_grade] ]
feedback = AssessmentFeedbackSerializer(feedback_model, data=feedback_dict)
feedback = AssessmentFeedbackSerializer(data=feedback_dict)
if not feedback.is_valid():
raise PeerAssessmentRequestError(feedback.errors)
try:
feedback.save()
feedback_model = feedback.save()
# Assessments associated with feedback must be saved after the row is
# committed to the database in order to associated the PKs across both
# tables.
feedback_model.assessments.add(*[assessment.id for assessment in assessments[:must_grade]])
except DatabaseError:
error_message = (
u"An error occurred saving assessment feedback for {}."
......
......@@ -274,6 +274,10 @@ def rubric_from_dict(rubric_dict):
class AssessmentFeedbackSerializer(serializers.ModelSerializer):
submission_uuid = serializers.CharField(source='submission_uuid')
helpfulness = serializers.IntegerField(source='helpfulness')
feedback = serializers.CharField(source='feedback')
assessments = AssessmentSerializer(many=True, default=None, required=False)
class Meta:
model = AssessmentFeedback
......@@ -281,5 +285,6 @@ class AssessmentFeedbackSerializer(serializers.ModelSerializer):
'submission_uuid',
'helpfulness',
'feedback',
'assessments',
)
......@@ -24,6 +24,7 @@ class GradeMixin(object):
context = {}
if status == "done":
feedback = peer_api.get_assessment_feedback(self.submission_uuid)
feedback_text = feedback.get('feedback', '') if feedback else ''
max_scores = peer_api.get_rubric_max_scores(self.submission_uuid)
path = 'openassessmentblock/grade/oa_grade_complete.html'
assessment_ui_model = self.get_assessment_module('peer-assessment')
......@@ -44,7 +45,7 @@ class GradeMixin(object):
student_submission["uuid"],
assessment_ui_model["must_be_graded_by"]
)
context["feedback_text"] = feedback.get('feedback', '')
context["feedback_text"] = feedback_text
context["student_submission"] = student_submission
context["peer_assessments"] = peer_assessments
context["self_assessment"] = self_assessment
......@@ -75,37 +76,34 @@ class GradeMixin(object):
def feedback_submit(self, data, suffix=''):
"""Attach the Assessment Feedback text to some submission."""
assessment_ui_model = self.get_assessment_module('peer-assessment') or {}
assessment_feedback = data.get('feedback', '')
if not assessment_feedback:
return {
'success': False,
'msg': _(u"No feedback given, so none recorded")
}
peer_assessment_error_message = ''
try:
peer_api.set_assessment_feedback(
assessment_ui_model.get('must_grade', 0),
assessment_ui_model['must_grade'],
{
'submission_uuid': self.submission_uuid,
'feedback': assessment_feedback,
'helpfulness': 0
}
)
except peer_api.PeerAssessmentInternalError, msg:
peer_assessment_error_message = msg
except peer_api.PeerAsessmentRequestError, msg:
peer_assessment_error_message = msg
if peer_assessment_error_message:
except (
peer_api.PeerAssessmentInternalError,
peer_api.PeerAssessmentRequestError
):
return {
'success': False,
'msg': peer_assessment_error_message,
}
else:
# Success!
return {
'success': True,
'msg': _(u"Feedback saved!")
'msg': _(
u"Assessment Feedback could not be saved due to an internal "
u"server error."
),
}
return {
'success': True,
'msg': _(u"Feedback saved!")
}
......@@ -322,12 +322,13 @@ OpenAssessment.BaseUI.prototype = {
feedback_assess: function() {
// Send the submission to the server
var feedback = $('#feedback__remarks__value', this.element).val();
var ui = this;
this.server.feedback_submit(feedback).done(
// When we have successfully sent the submission, textarea no longer editable
console.log("Feedback to the assessments submitted, thanks!")
).fail(function(errMsg) {
// TODO: display to the user
console.log(errMsg);
ui.toggleActionError('feedback_assess', errMsg);
});
},
......
......@@ -163,6 +163,20 @@ OpenAssessment.Server.prototype = {
/**
* Send feedback on assessments to the XBlock.
* Args:
* feedback: The feedback given on a series of assessments associated
* with this current submission.
*
* Returns:
* A JQuery promise, which resolves with no args if successful and
* fails with an error message otherwise.
*
* Example:
* server.feedback_submit("I dislike my reviews.").done(
* console.log("Success!");
* ).fail(function(errMsg) {
* console.log("Error: " + errMsg);
* });
*/
feedback_submit: function(feedback) {
var url = this.url('feedback_submit');
......
......@@ -11,7 +11,7 @@ export DJANGO_SETTINGS_MODULE="settings.dev"
# Create the database
echo "Updating the database..."
python manage.py syncdb --migrate --noinput -v 0
python manage.py syncdb --migrate -v 0
echo "Starting server..."
python manage.py runserver_plus "${@:1}"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment