Commit 53f48f60 by Clinton Blackburn

Replaced course_key with course_id

Change-Id: I33860a35165f42f67be8b5e0738d47540250f55b
parent b4034977
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"pk": 1, "pk": 1,
"model": "v0.course", "model": "v0.course",
"fields": { "fields": {
"course_key": "edX/DemoX/Demo_Course" "course_id": "edX/DemoX/Demo_Course"
} }
} }
] ]
...@@ -2,5 +2,5 @@ from django.db import models ...@@ -2,5 +2,5 @@ from django.db import models
class CourseManager(models.Manager): class CourseManager(models.Manager):
def get_by_natural_key(self, course_key): def get_by_natural_key(self, course_id):
return self.get(course_key=course_key) return self.get(course_id=course_id)
...@@ -3,8 +3,9 @@ from analytics_data_api.v0.managers import CourseManager ...@@ -3,8 +3,9 @@ from analytics_data_api.v0.managers import CourseManager
class Course(models.Model): class Course(models.Model):
course_id = models.CharField(unique=True, max_length=255)
objects = CourseManager() # pylint: disable=no-value-for-parameter objects = CourseManager() # pylint: disable=no-value-for-parameter
course_key = models.CharField(unique=True, max_length=255)
class Meta(object): class Meta(object):
db_table = 'courses' db_table = 'courses'
...@@ -23,9 +24,9 @@ class CourseActivityByWeek(models.Model): ...@@ -23,9 +24,9 @@ class CourseActivityByWeek(models.Model):
count = models.IntegerField() count = models.IntegerField()
@classmethod @classmethod
def get_most_recent(cls, course_key, activity_type): def get_most_recent(cls, course_id, activity_type):
"""Activity for the week that was mostly recently computed.""" """Activity for the week that was mostly recently computed."""
return cls.objects.filter(course__course_key=course_key, activity_type=activity_type).latest('interval_end') return cls.objects.filter(course__course_id=course_id, activity_type=activity_type).latest('interval_end')
class BaseCourseEnrollment(models.Model): class BaseCourseEnrollment(models.Model):
......
...@@ -9,11 +9,11 @@ class CourseActivityByWeekSerializer(serializers.ModelSerializer): ...@@ -9,11 +9,11 @@ class CourseActivityByWeekSerializer(serializers.ModelSerializer):
This table is managed by the data pipeline, and records can be removed and added at any time. The id for a This table is managed by the data pipeline, and records can be removed and added at any time. The id for a
particular record is likely to change unexpectedly so we avoid exposing it. particular record is likely to change unexpectedly so we avoid exposing it.
""" """
course_key = serializers.SerializerMethodField('get_course_key') course_id = serializers.SerializerMethodField('get_course_id')
def get_course_key(self, obj): def get_course_id(self, obj):
return obj.course.course_key return obj.course.course_id
class Meta(object): class Meta(object):
model = CourseActivityByWeek model = CourseActivityByWeek
fields = ('interval_start', 'interval_end', 'activity_type', 'count', 'course_key') fields = ('interval_start', 'interval_end', 'activity_type', 'count', 'course_id')
...@@ -99,8 +99,8 @@ class OperationalEndpointsTest(TestCaseWithAuthentication): ...@@ -99,8 +99,8 @@ class OperationalEndpointsTest(TestCaseWithAuthentication):
class CourseActivityLastWeekTest(TestCaseWithAuthentication): class CourseActivityLastWeekTest(TestCaseWithAuthentication):
def setUp(self): def setUp(self):
super(CourseActivityLastWeekTest, self).setUp() super(CourseActivityLastWeekTest, self).setUp()
self.course_key = 'edX/DemoX/Demo_Course' self.course_id = 'edX/DemoX/Demo_Course'
self.course = G(Course, course_key=self.course_key) self.course = G(Course, course_id=self.course_id)
interval_start = '2014-05-24T00:00:00Z' interval_start = '2014-05-24T00:00:00Z'
interval_end = '2014-06-01T00:00:00Z' interval_end = '2014-06-01T00:00:00Z'
G(CourseActivityByWeek, course=self.course, interval_start=interval_start, interval_end=interval_end, G(CourseActivityByWeek, course=self.course, interval_start=interval_start, interval_end=interval_end,
...@@ -113,14 +113,14 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication): ...@@ -113,14 +113,14 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication):
activity_type='played_video', count=400) activity_type='played_video', count=400)
def test_activity(self): def test_activity(self):
response = self.authenticated_get('/api/v0/courses/{0}/recent_activity'.format(self.course_key)) response = self.authenticated_get('/api/v0/courses/{0}/recent_activity'.format(self.course_id))
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
self.assertEquals(response.data, self.get_activity_record()) self.assertEquals(response.data, self.get_activity_record())
@staticmethod @staticmethod
def get_activity_record(**kwargs): def get_activity_record(**kwargs):
default = { default = {
'course_key': 'edX/DemoX/Demo_Course', 'course_id': 'edX/DemoX/Demo_Course',
'interval_start': datetime(2014, 5, 24, 0, 0, tzinfo=pytz.utc), 'interval_start': datetime(2014, 5, 24, 0, 0, tzinfo=pytz.utc),
'interval_end': datetime(2014, 6, 1, 0, 0, tzinfo=pytz.utc), 'interval_end': datetime(2014, 6, 1, 0, 0, tzinfo=pytz.utc),
'activity_type': 'any', 'activity_type': 'any',
...@@ -130,10 +130,10 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication): ...@@ -130,10 +130,10 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication):
return default return default
def test_activity_auth(self): def test_activity_auth(self):
response = self.client.get('/api/v0/courses/{0}/recent_activity'.format(self.course_key)) response = self.client.get('/api/v0/courses/{0}/recent_activity'.format(self.course_id))
self.assertEquals(response.status_code, 401) self.assertEquals(response.status_code, 401)
def test_url_encoded_course_key(self): def test_url_encoded_course_id(self):
response = self.authenticated_get('/api/v0/courses/edX%2FDemoX%2FDemo_Course/recent_activity') response = self.authenticated_get('/api/v0/courses/edX%2FDemoX%2FDemo_Course/recent_activity')
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
self.assertEquals(response.data, self.get_activity_record()) self.assertEquals(response.data, self.get_activity_record())
...@@ -141,21 +141,21 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication): ...@@ -141,21 +141,21 @@ class CourseActivityLastWeekTest(TestCaseWithAuthentication):
def test_video_activity(self): def test_video_activity(self):
activity_type = 'played_video' activity_type = 'played_video'
response = self.authenticated_get('/api/v0/courses/{0}/recent_activity?activity_type={1}'.format( response = self.authenticated_get('/api/v0/courses/{0}/recent_activity?activity_type={1}'.format(
self.course_key, activity_type)) self.course_id, activity_type))
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
self.assertEquals(response.data, self.get_activity_record(activity_type=activity_type, count=400)) self.assertEquals(response.data, self.get_activity_record(activity_type=activity_type, count=400))
def test_unknown_activity(self): def test_unknown_activity(self):
activity_type = 'missing_activity_type' activity_type = 'missing_activity_type'
response = self.authenticated_get('/api/v0/courses/{0}/recent_activity?activity_type={1}'.format( response = self.authenticated_get('/api/v0/courses/{0}/recent_activity?activity_type={1}'.format(
self.course_key, activity_type)) self.course_id, activity_type))
self.assertEquals(response.status_code, 404) self.assertEquals(response.status_code, 404)
def test_unknown_course_key(self): def test_unknown_course_id(self):
response = self.authenticated_get('/api/v0/courses/{0}/recent_activity'.format('foo')) response = self.authenticated_get('/api/v0/courses/{0}/recent_activity'.format('foo'))
self.assertEquals(response.status_code, 404) self.assertEquals(response.status_code, 404)
def test_missing_course_key(self): def test_missing_course_id(self):
response = self.authenticated_get('/api/v0/courses/recent_activity') response = self.authenticated_get('/api/v0/courses/recent_activity')
self.assertEquals(response.status_code, 404) self.assertEquals(response.status_code, 404)
...@@ -164,21 +164,21 @@ class CourseEnrollmentViewTestCase(object): ...@@ -164,21 +164,21 @@ class CourseEnrollmentViewTestCase(object):
model = None model = None
path = None path = None
def _get_non_existent_course_key(self): def _get_non_existent_course_id(self):
course_key = random.randint(100, 9999) course_id = random.randint(100, 9999)
if not Course.objects.filter(course_key=course_key).exists(): if not Course.objects.filter(course_id=course_id).exists():
return course_key return course_id
return self._get_non_existent_course_key() return self._get_non_existent_course_id()
def test_get_not_found(self): def test_get_not_found(self):
''' '''
Requests made against non-existent courses should return a 404 Requests made against non-existent courses should return a 404
''' '''
course_key = self._get_non_existent_course_key() course_id = self._get_non_existent_course_id()
self.assertFalse(self.model.objects.filter(course__course_key=course_key).exists()) # pylint: disable=no-member self.assertFalse(self.model.objects.filter(course__course_id=course_id).exists()) # pylint: disable=no-member
response = self.authenticated_get('/api/v0/courses/%s%s' % (course_key, self.path)) # pylint: disable=no-member response = self.authenticated_get('/api/v0/courses/%s%s' % (course_id, self.path)) # pylint: disable=no-member
self.assertEquals(response.status_code, 404) # pylint: disable=no-member self.assertEquals(response.status_code, 404) # pylint: disable=no-member
def test_get(self): def test_get(self):
...@@ -196,7 +196,7 @@ class CourseEnrollmentByBirthYearViewTests(TestCaseWithAuthentication, CourseEnr ...@@ -196,7 +196,7 @@ class CourseEnrollmentByBirthYearViewTests(TestCaseWithAuthentication, CourseEnr
cls.ce2 = G(CourseEnrollmentByBirthYear, course=cls.course, birth_year=1986) cls.ce2 = G(CourseEnrollmentByBirthYear, course=cls.course, birth_year=1986)
def test_get(self): def test_get(self):
response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_key, self.path,)) response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_id, self.path,))
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
expected = { expected = {
...@@ -220,7 +220,7 @@ class CourseEnrollmentByEducationViewTests(TestCaseWithAuthentication, CourseEnr ...@@ -220,7 +220,7 @@ class CourseEnrollmentByEducationViewTests(TestCaseWithAuthentication, CourseEnr
cls.ce2 = G(CourseEnrollmentByEducation, course=cls.course, education_level=cls.el2) cls.ce2 = G(CourseEnrollmentByEducation, course=cls.course, education_level=cls.el2)
def test_get(self): def test_get(self):
response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_key, self.path,)) response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_id, self.path,))
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
expected = { expected = {
...@@ -242,7 +242,7 @@ class CourseEnrollmentByGenderViewTests(TestCaseWithAuthentication, CourseEnroll ...@@ -242,7 +242,7 @@ class CourseEnrollmentByGenderViewTests(TestCaseWithAuthentication, CourseEnroll
cls.ce2 = G(CourseEnrollmentByGender, course=cls.course, gender='f') cls.ce2 = G(CourseEnrollmentByGender, course=cls.course, gender='f')
def test_get(self): def test_get(self):
response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_key, self.path,)) response = self.authenticated_get('/api/v0/courses/%s%s' % (self.course.course_id, self.path,))
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
expected = { expected = {
...@@ -255,8 +255,8 @@ class CourseEnrollmentByGenderViewTests(TestCaseWithAuthentication, CourseEnroll ...@@ -255,8 +255,8 @@ class CourseEnrollmentByGenderViewTests(TestCaseWithAuthentication, CourseEnroll
class CourseManagerTests(TestCase): class CourseManagerTests(TestCase):
def test_get_by_natural_key(self): def test_get_by_natural_key(self):
course_key = 'edX/DemoX/Demo_Course' course_id = 'edX/DemoX/Demo_Course'
self.assertRaises(ObjectDoesNotExist, Course.objects.get_by_natural_key, course_key) self.assertRaises(ObjectDoesNotExist, Course.objects.get_by_natural_key, course_id)
course = G(Course, course_key=course_key) course = G(Course, course_id=course_id)
self.assertEqual(course, Course.objects.get_by_natural_key(course_key)) self.assertEqual(course, Course.objects.get_by_natural_key(course_id))
...@@ -19,4 +19,4 @@ urlpatterns = patterns( ...@@ -19,4 +19,4 @@ urlpatterns = patterns(
) )
for path, view, name in COURSE_URLS: for path, view, name in COURSE_URLS:
urlpatterns += patterns('', url(r'^(?P<course_key>.+)/' + re.escape(path) + r'$', view.as_view(), name=name)) urlpatterns += patterns('', url(r'^(?P<course_id>.+)/' + re.escape(path) + r'$', view.as_view(), name=name))
...@@ -18,7 +18,7 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView): ...@@ -18,7 +18,7 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView):
The representation has the following fields: The representation has the following fields:
<ul> <ul>
<li>course_key: The ID of the course whose activity is described (e.g. edX/DemoX/Demo_Course).</li> <li>course_id: The string identifying the course whose activity is described (e.g. edX/DemoX/Demo_Course).</li>
- interval_start: All data from this timestamp up to the `interval_end` was considered when computing this data - interval_start: All data from this timestamp up to the `interval_end` was considered when computing this data
point. point.
- interval_end: All data from `interval_start` up to this timestamp was considered when computing this data point. - interval_end: All data from `interval_start` up to this timestamp was considered when computing this data point.
...@@ -41,13 +41,13 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView): ...@@ -41,13 +41,13 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
"""Select the activity report for the given course and activity type.""" """Select the activity report for the given course and activity type."""
course_key = self.kwargs.get('course_key') course_id = self.kwargs.get('course_id')
activity_type = self.request.QUERY_PARAMS.get('activity_type', 'any') activity_type = self.request.QUERY_PARAMS.get('activity_type', 'any')
activity_type = activity_type.lower() activity_type = activity_type.lower()
try: try:
print CourseActivityByWeek.objects.all() print CourseActivityByWeek.objects.all()
return CourseActivityByWeek.get_most_recent(course_key, activity_type) return CourseActivityByWeek.get_most_recent(course_id, activity_type)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404 raise Http404
...@@ -65,8 +65,8 @@ class AbstractCourseEnrollmentView(APIView): ...@@ -65,8 +65,8 @@ class AbstractCourseEnrollmentView(APIView):
if not self.model: if not self.model:
raise NotImplementedError('Subclasses must specify a model!') raise NotImplementedError('Subclasses must specify a model!')
course_key = self.kwargs['course_key'] course_id = self.kwargs['course_id']
data = self.model.objects.filter(course__course_key=course_key) data = self.model.objects.filter(course__course_id=course_id)
if not data: if not data:
raise Http404 raise Http404
......
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