Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-analytics-data-api
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-analytics-data-api
Commits
3afb4103
Commit
3afb4103
authored
Oct 13, 2014
by
dylanrhodes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added REST API for grade_distribution and sequential_open_distribution tables and test cases
parent
29437878
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
157 additions
and
0 deletions
+157
-0
analytics_data_api/v0/models.py
+26
-0
analytics_data_api/v0/serializers.py
+32
-0
analytics_data_api/v0/tests/test_views.py
+60
-0
analytics_data_api/v0/urls/problems.py
+5
-0
analytics_data_api/v0/views/problems.py
+34
-0
No files found.
analytics_data_api/v0/models.py
View file @
3afb4103
...
...
@@ -119,3 +119,29 @@ class CourseEnrollmentByCountry(BaseCourseEnrollment):
db_table
=
'course_enrollment_location_current'
ordering
=
(
'date'
,
'course_id'
,
'country_code'
)
unique_together
=
[(
'course_id'
,
'date'
,
'country_code'
)]
class
GradeDistribution
(
models
.
Model
):
""" Each row stores the count of a particular grade on a module for a given course. """
class
Meta
(
object
):
db_table
=
'grade_distribution'
module_id
=
models
.
CharField
(
db_index
=
True
,
max_length
=
255
,
db_column
=
'module_id'
)
course_id
=
models
.
CharField
(
db_index
=
True
,
max_length
=
255
,
db_column
=
'course_id'
)
grade
=
models
.
IntegerField
(
db_column
=
'grade'
)
max_grade
=
models
.
IntegerField
(
db_column
=
'max_grade'
)
count
=
models
.
IntegerField
(
db_column
=
'count'
)
created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
db_column
=
'created'
)
class
SequentialOpenDistribution
(
models
.
Model
):
""" Each row stores the count of views a particular module has had in a given course. """
class
Meta
(
object
):
db_table
=
'sequential_open_distribution'
module_id
=
models
.
CharField
(
db_index
=
True
,
max_length
=
255
,
db_column
=
'module_id'
)
course_id
=
models
.
CharField
(
db_index
=
True
,
max_length
=
255
,
db_column
=
'course_id'
)
count
=
models
.
IntegerField
(
db_column
=
'count'
)
created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
db_column
=
'created'
)
analytics_data_api/v0/serializers.py
View file @
3afb4103
...
...
@@ -54,6 +54,38 @@ class ProblemResponseAnswerDistributionSerializer(serializers.ModelSerializer):
)
class
GradeDistributionSerializer
(
serializers
.
ModelSerializer
):
"""
Representation of the grade_distribution table without id
"""
class
Meta
(
object
):
model
=
models
.
GradeDistribution
fields
=
(
'module_id'
,
'course_id'
,
'grade'
,
'max_grade'
,
'count'
,
'created'
)
class
SequentialOpenDistributionSerializer
(
serializers
.
ModelSerializer
):
"""
Representation of the sequential_open_distribution table without id
"""
class
Meta
(
object
):
model
=
models
.
SequentialOpenDistribution
fields
=
(
'module_id'
,
'course_id'
,
'count'
,
'created'
)
class
BaseCourseEnrollmentModelSerializer
(
serializers
.
ModelSerializer
):
date
=
serializers
.
DateField
(
format
=
settings
.
DATE_FORMAT
)
created
=
serializers
.
DateTimeField
(
format
=
settings
.
DATETIME_FORMAT
)
...
...
analytics_data_api/v0/tests/test_views.py
View file @
3afb4103
...
...
@@ -15,6 +15,8 @@ from analytics_data_api.v0 import models
from
analytics_data_api.v0.constants
import
UNKNOWN_COUNTRY
,
UNKNOWN_COUNTRY_CODE
from
analytics_data_api.v0.models
import
CourseActivityWeekly
from
analytics_data_api.v0.serializers
import
ProblemResponseAnswerDistributionSerializer
from
analytics_data_api.v0.serializers
import
GradeDistributionSerializer
from
analytics_data_api.v0.serializers
import
SequentialOpenDistributionSerializer
from
analytics_data_api.v0.tests.utils
import
flatten
from
analyticsdataserver.tests
import
TestCaseWithAuthentication
...
...
@@ -429,3 +431,61 @@ class CourseActivityWeeklyViewTests(CourseViewTestCaseMixin, TestCaseWithAuthent
expected
=
self
.
format_as_response
(
*
self
.
model
.
objects
.
all
())
self
.
assertEqual
(
len
(
expected
),
2
)
self
.
assertIntervalFilteringWorks
(
expected
,
self
.
interval_start
,
interval_end
+
datetime
.
timedelta
(
days
=
1
))
# pylint: disable=no-member,no-value-for-parameter
class
GradeDistributionTests
(
TestCaseWithAuthentication
):
path
=
'/grade_distribution'
maxDiff
=
None
@classmethod
def
setUpClass
(
cls
):
cls
.
course_id
=
"org/class/test"
cls
.
module_id
=
"i4x://org/class/test/problem/RANDOM_NUMBER"
cls
.
ad1
=
G
(
models
.
GradeDistribution
,
course_id
=
cls
.
course_id
,
module_id
=
cls
.
module_id
,
)
def
test_get
(
self
):
response
=
self
.
authenticated_get
(
'/api/v0/problems/
%
s
%
s'
%
(
self
.
module_id
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
200
)
expected_dict
=
GradeDistributionSerializer
(
self
.
ad1
)
.
data
actual_list
=
response
.
data
self
.
assertEquals
(
len
(
actual_list
),
1
)
self
.
assertDictEqual
(
actual_list
[
0
],
expected_dict
)
def
test_get_404
(
self
):
response
=
self
.
authenticated_get
(
'/api/v0/problems/
%
s
%
s'
%
(
"DOES-NOT-EXIST"
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
404
)
# pylint: disable=no-member,no-value-for-parameter
class
SequentialOpenDistributionTests
(
TestCaseWithAuthentication
):
path
=
'/sequential_open_distribution'
maxDiff
=
None
@classmethod
def
setUpClass
(
cls
):
cls
.
course_id
=
"org/class/test"
cls
.
module_id
=
"i4x://org/class/test/problem/RANDOM_NUMBER"
cls
.
ad1
=
G
(
models
.
SequentialOpenDistribution
,
course_id
=
cls
.
course_id
,
module_id
=
cls
.
module_id
,
)
def
test_get
(
self
):
response
=
self
.
authenticated_get
(
'/api/v0/problems/
%
s
%
s'
%
(
self
.
module_id
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
200
)
expected_dict
=
SequentialOpenDistributionSerializer
(
self
.
ad1
)
.
data
actual_list
=
response
.
data
self
.
assertEquals
(
len
(
actual_list
),
1
)
self
.
assertDictEqual
(
actual_list
[
0
],
expected_dict
)
def
test_get_404
(
self
):
response
=
self
.
authenticated_get
(
'/api/v0/problems/
%
s
%
s'
%
(
"DOES-NOT-EXIST"
,
self
.
path
))
self
.
assertEquals
(
response
.
status_code
,
404
)
analytics_data_api/v0/urls/problems.py
View file @
3afb4103
...
...
@@ -3,13 +3,18 @@ import re
from
django.conf.urls
import
patterns
,
url
from
analytics_data_api.v0.views.problems
import
ProblemResponseAnswerDistributionView
from
analytics_data_api.v0.views.problems
import
GradeDistributionView
from
analytics_data_api.v0.views.problems
import
SequentialOpenDistributionView
PROBLEM_URLS
=
[
(
'answer_distribution'
,
ProblemResponseAnswerDistributionView
,
'answer_distribution'
),
(
'grade_distribution'
,
GradeDistributionView
,
'grade_distribution'
),
]
urlpatterns
=
patterns
(
''
,
url
(
r'^(?P<module_id>.+)/sequential_open_distribution$'
,
SequentialOpenDistributionView
.
as_view
(),
name
=
'sequential_open_distribution'
),
)
for
path
,
view
,
name
in
PROBLEM_URLS
:
...
...
analytics_data_api/v0/views/problems.py
View file @
3afb4103
...
...
@@ -3,6 +3,12 @@ from rest_framework import generics
from
analytics_data_api.v0.models
import
ProblemResponseAnswerDistribution
from
analytics_data_api.v0.serializers
import
ProblemResponseAnswerDistributionSerializer
from
analytics_data_api.v0.models
import
GradeDistribution
from
analytics_data_api.v0.serializers
import
GradeDistributionSerializer
from
analytics_data_api.v0.models
import
SequentialOpenDistribution
from
analytics_data_api.v0.serializers
import
SequentialOpenDistributionSerializer
class
ProblemResponseAnswerDistributionView
(
generics
.
ListAPIView
):
"""
...
...
@@ -18,3 +24,31 @@ class ProblemResponseAnswerDistributionView(generics.ListAPIView):
"""Select all the answer distribution response having to do with this usage of the problem."""
problem_id
=
self
.
kwargs
.
get
(
'problem_id'
)
return
ProblemResponseAnswerDistribution
.
objects
.
filter
(
module_id
=
problem_id
)
class
GradeDistributionView
(
generics
.
ListAPIView
):
"""
Distribution of grades for a particular module in a given course
"""
serializer_class
=
GradeDistributionSerializer
allow_empty
=
False
def
get_queryset
(
self
):
"""Select all grade distributions for a particular module"""
problem_id
=
self
.
kwargs
.
get
(
'problem_id'
)
return
GradeDistribution
.
objects
.
filter
(
module_id
=
problem_id
)
class
SequentialOpenDistributionView
(
generics
.
ListAPIView
):
"""
Distribution of view counts for a particular module in a given course
"""
serializer_class
=
SequentialOpenDistributionSerializer
allow_empty
=
False
def
get_queryset
(
self
):
"""Select the view count for a specific module"""
module_id
=
self
.
kwargs
.
get
(
'module_id'
)
return
SequentialOpenDistribution
.
objects
.
filter
(
module_id
=
module_id
)
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