Skip to content
Snippets Groups Projects

Fix relation between MultipleChoiceOption and FeedbackOption

Merged Ghost User requested to merge fix/mco-feedback-rel into develop
1 unresolved thread
+ 40
16
from flask_restful import Resource, reqparse
from ..database import db, MultipleChoiceOption
from ..database import db, MultipleChoiceOption, FeedbackOption
def set_mc_data(mc_entry, name, x, y, mc_type, problem_id, feedback_id, label):
def set_mc_data(mc_entry, name, x, y, mc_type, feedback_id, label):
"""Sets the data of a MultipleChoiceOption ORM object.
Parameters:
-----------
mc_entry: The MultipleChoiceOption object
name: The name of the MultipleChoiceOption widget
x: the x-position of the MultipleChoiceOption object.
y: the y-position of the MultipleChoiceOption object.
problem_id: the problem the MultipleChoiceOption refers to
type: the polymorphic type used to distinguish the MultipleChoiceOption widget
from other widgets
feedback_id: the feedback the MultipleChoiceOption refers to
label: label for the checkbox that this MultipleChoiceOption represents
"""
@@ -19,7 +21,6 @@ def set_mc_data(mc_entry, name, x, y, mc_type, problem_id, feedback_id, label):
mc_entry.x = x
mc_entry.y = y
mc_entry.type = mc_type
mc_entry.problem_id = problem_id
mc_entry.feedback_id = feedback_id
mc_entry.label = label
@@ -33,8 +34,7 @@ class MultipleChoice(Resource):
put_parser.add_argument('x', type=int, required=True)
put_parser.add_argument('y', type=int, required=True)
put_parser.add_argument('label', type=str, required=False)
put_parser.add_argument('problem_id', type=int, required=True)
put_parser.add_argument('feedback_id', type=int, required=True)
put_parser.add_argument('problem_id', type=int, required=True) # Used for FeedbackOption
def put(self, id=None):
"""Adds or updates a multiple choice option to the database
@@ -42,6 +42,10 @@ class MultipleChoice(Resource):
If the parameter id is not present, a new multiple choice question
will be inserted with the data provided in the request body.
For each new multiple choice option, a feedback option that links to
the multiple choice option is inserted into the database. The new
feedback option also refers to same problem as the MultipleChoiceOption
Parameters
----------
id: The id of the multiple choice option
@@ -55,20 +59,26 @@ class MultipleChoice(Resource):
y = args['y']
label = args['label']
problem_id = args['problem_id']
feedback_id = args['feedback_id']
# TODO: Set type here or add to request?
mc_type = 'mcq_widget'
if not id:
# Insert new empty feedback option that links to the same problem
new_feedback_option = FeedbackOption(problem_id=problem_id, text='')
db.session.add(new_feedback_option)
+3
db.session.commit()
# Insert new entry into the database
mc_entry = MultipleChoiceOption()
set_mc_data(mc_entry, name, x, y, mc_type, problem_id, feedback_id, label)
set_mc_data(mc_entry, name, x, y, mc_type, new_feedback_option.id, label)
db.session.add(mc_entry)
db.session.commit()
return dict(status=200, message=f'New multiple choice question with id {mc_entry.id} inserted'), 200
return dict(status=200, mult_choice_id=mc_entry.id, feedback_id=new_feedback_option.id,
message=f'New multiple choice question with id {mc_entry.id} inserted. '
+ f'New feedback option with id {new_feedback_option.id} inserted.'), 200
# Update existing entry otherwise
mc_entry = MultipleChoiceOption.query.get(id)
@@ -76,7 +86,7 @@ class MultipleChoice(Resource):
if not mc_entry:
return dict(status=404, message=f"Multiple choice question with id {id} does not exist"), 404
set_mc_data(mc_entry, name, x, y, mc_type, problem_id, feedback_id, label)
set_mc_data(mc_entry, name, x, y, mc_type, label)
db.session.commit()
return dict(status=200, message=f'Multiple choice question with id {id} updated'), 200
@@ -103,20 +113,21 @@ class MultipleChoice(Resource):
'x': mult_choice.x,
'y': mult_choice.y,
'type': mult_choice.type,
'problem_id': mult_choice.problem_id
'feedback_id': mult_choice.feedback_id
}
# Nullable database fields
if mult_choice.label:
json['label'] = mult_choice.label
if mult_choice.feedback_id:
json['feedback_id'] = mult_choice.feedback_id
return json
def delete(self, id):
"""Deletes a multiple choice option from the database
"""Deletes a multiple choice option from the database.
Also deletes the associated feedback option with this multiple choice option.
An error will be thrown if the user tries to delete a feedback option
associated with a multiple choice option in a finalized exam.
Parameters
----------
@@ -131,7 +142,20 @@ class MultipleChoice(Resource):
if not mult_choice:
return dict(status=404, message=f'Multiple choice question with id {id} does not exist.'), 404
if not mult_choice.feedback:
return dict(status=404, message=f'Multiple choice question with id {id}'
+ ' is not associated with a feedback option.'), 404
# Check if the exam is finalized, do not delete the multiple choice option otherwise
exam = mult_choice.feedback.problem.exam
if exam.finalized:
return dict(status=401, message='Cannot delete feedback option'
+ ' attached to a multiple choice option in a finalized exam.'), 401
db.session.delete(mult_choice)
db.session.delete(mult_choice.feedback)
db.session.commit()
return dict(status=200, message=f'Multiple choice question with id {id} deleted.'), 200
return dict(status=200, message=f'Multiple choice question with id {id} deleted.'
+ f'Feedback option with id {mult_choice.feedback_id} deleted.'), 200
Loading