Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-submissions
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-submissions
Commits
db4c29b5
Commit
db4c29b5
authored
Feb 18, 2016
by
Eric Fischer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #33 from edx/efischer/soft_delete_sub
Soft-delete Submissions to reset student state
parents
02ccd59d
86b9122c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
4 deletions
+78
-4
submissions/api.py
+17
-4
submissions/migrations/0003_submission_status.py
+19
-0
submissions/models.py
+21
-0
submissions/tests/test_api.py
+21
-0
No files found.
submissions/api.py
View file @
db4c29b5
...
...
@@ -217,7 +217,7 @@ def get_submission(submission_uuid, read_replica=False):
msg
=
"submission_uuid ({!r}) must be a string type"
.
format
(
submission_uuid
)
)
cache_key
=
"submissions.submission.{}"
.
format
(
submission_uuid
)
cache_key
=
Submission
.
get_cache_key
(
submission_uuid
)
try
:
cached_submission_data
=
cache
.
get
(
cache_key
)
except
Exception
as
ex
:
...
...
@@ -627,8 +627,10 @@ def get_latest_score_for_submission(submission_uuid, read_replica=False):
"""
try
:
# Ensure that submission_uuid is valid before fetching score
submission_model
=
Submission
.
objects
.
get
(
uuid
=
submission_uuid
)
score_qs
=
Score
.
objects
.
filter
(
submission__uuid
=
submission_uuid
submission__uuid
=
submission_
model
.
uuid
)
.
order_by
(
"-id"
)
.
select_related
(
"submission"
)
if
read_replica
:
...
...
@@ -637,13 +639,13 @@ def get_latest_score_for_submission(submission_uuid, read_replica=False):
score
=
score_qs
[
0
]
if
score
.
is_hidden
():
return
None
except
IndexError
:
except
(
IndexError
,
Submission
.
DoesNotExist
)
:
return
None
return
ScoreSerializer
(
score
)
.
data
def
reset_score
(
student_id
,
course_id
,
item_id
):
def
reset_score
(
student_id
,
course_id
,
item_id
,
clear_state
=
False
):
"""
Reset scores for a specific student on a specific problem.
...
...
@@ -655,6 +657,7 @@ def reset_score(student_id, course_id, item_id):
student_id (unicode): The ID of the student for whom to reset scores.
course_id (unicode): The ID of the course containing the item to reset.
item_id (unicode): The ID of the item for which to reset scores.
clear_state (bool): If True, will appear to delete any submissions associated with the specified StudentItem
Returns:
None
...
...
@@ -684,6 +687,16 @@ def reset_score(student_id, course_id, item_id):
item_id
=
item_id
,
)
if
clear_state
:
for
sub
in
student_item
.
submission_set
.
all
():
# soft-delete the Submission
sub
.
status
=
Submission
.
DELETED
sub
.
save
(
update_fields
=
[
"status"
])
# Also clear out cached values
cache_key
=
Submission
.
get_cache_key
(
sub
.
uuid
)
cache
.
delete
(
cache_key
)
except
DatabaseError
:
msg
=
(
u"Error occurred while reseting scores for"
...
...
submissions/migrations/0003_submission_status.py
0 → 100644
View file @
db4c29b5
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'submissions'
,
'0002_auto_20151119_0913'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'submission'
,
name
=
'status'
,
field
=
models
.
CharField
(
default
=
b
'A'
,
max_length
=
1
,
choices
=
[(
b
'D'
,
b
'Deleted'
),
(
b
'A'
,
b
'Active'
)]),
),
]
submissions/models.py
View file @
db4c29b5
...
...
@@ -124,6 +124,27 @@ class Submission(models.Model):
# name so it continues to use `raw_answer`.
answer
=
JSONField
(
blank
=
True
,
db_column
=
"raw_answer"
)
# Has this submission been soft-deleted? This allows instructors to reset student
# state on an item, while preserving the previous value for potential analytics use.
DELETED
=
'D'
ACTIVE
=
'A'
STATUS_CHOICES
=
(
(
DELETED
,
'Deleted'
),
(
ACTIVE
,
'Active'
),
)
status
=
models
.
CharField
(
max_length
=
1
,
choices
=
STATUS_CHOICES
,
default
=
ACTIVE
)
# Override the default Manager with our custom one to filter out soft-deleted items
class
SoftDeletedManager
(
models
.
Manager
):
def
get_queryset
(
self
):
return
super
(
Submission
.
SoftDeletedManager
,
self
)
.
get_queryset
()
.
exclude
(
status
=
Submission
.
DELETED
)
objects
=
SoftDeletedManager
()
@staticmethod
def
get_cache_key
(
sub_uuid
):
return
"submissions.submission.{}"
.
format
(
sub_uuid
)
def
__repr__
(
self
):
return
repr
(
dict
(
uuid
=
self
.
uuid
,
...
...
submissions/tests/test_api.py
View file @
db4c29b5
...
...
@@ -573,6 +573,27 @@ class TestSubmissionsApi(TestCase):
)
self
.
assertEqual
(
cached_scores
,
scores
)
def
test_clear_state
(
self
):
# Create a submission, give it a score, and verify that score exists
submission
=
api
.
create_submission
(
STUDENT_ITEM
,
ANSWER_ONE
)
api
.
set_score
(
submission
[
"uuid"
],
11
,
12
)
score
=
api
.
get_score
(
STUDENT_ITEM
)
self
.
_assert_score
(
score
,
11
,
12
)
self
.
assertEqual
(
score
[
'submission_uuid'
],
submission
[
'uuid'
])
# Reset the score with clear_state=True
# This should set the submission's score to None, and make it unavailable to get_submissions
api
.
reset_score
(
STUDENT_ITEM
[
"student_id"
],
STUDENT_ITEM
[
"course_id"
],
STUDENT_ITEM
[
"item_id"
],
clear_state
=
True
,
)
score
=
api
.
get_score
(
STUDENT_ITEM
)
self
.
assertIsNone
(
score
)
subs
=
api
.
get_submissions
(
STUDENT_ITEM
)
self
.
assertEqual
(
subs
,
[])
@raises
(
api
.
SubmissionRequestError
)
def
test_error_on_get_top_submissions_too_few
(
self
):
student_item
=
copy
.
deepcopy
(
STUDENT_ITEM
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment