Commit d4de932c by chrisndodge

Merge pull request #6386 from edx/cdodge/WL-137-normalize-user-profile-meta-column

[WL-137] allow for student profile downloads to query into 'meta' field in the Us...
parents 5855587a 34d200ff
......@@ -3,6 +3,7 @@ Student and course analytics.
Serve miscellaneous course and student data
"""
import json
from shoppingcart.models import (
PaidCourseRegistration, CouponRedemption, Invoice, CourseRegCodeItem,
OrderTypes, RegistrationCodeRedemption, CourseRegistrationCode
......@@ -187,6 +188,15 @@ def enrolled_students_features(course_key, features):
student_features = [x for x in STUDENT_FEATURES if x in features]
profile_features = [x for x in PROFILE_FEATURES if x in features]
# For data extractions on the 'meta' field
# the feature name should be in the format of 'meta.foo' where
# 'foo' is the keyname in the meta dictionary
meta_features = []
for feature in features:
if 'meta.' in feature:
meta_key = feature.split('.')[1]
meta_features.append((feature, meta_key))
student_dict = dict((feature, getattr(student, feature))
for feature in student_features)
profile = student.profile
......@@ -195,6 +205,11 @@ def enrolled_students_features(course_key, features):
for feature in profile_features)
student_dict.update(profile_dict)
# now featch the requested meta fields
meta_dict = json.loads(profile.meta) if profile.meta else {}
for meta_feature, meta_key in meta_features:
student_dict[meta_feature] = meta_dict.get(meta_key)
if include_cohort_column:
# Note that we use student.course_groups.all() here instead of
# student.course_groups.filter(). The latter creates a fresh query,
......
......@@ -2,6 +2,7 @@
Tests for instructor.basic
"""
import json
from student.models import CourseEnrollment
from django.core.urlresolvers import reverse
from mock import patch
......@@ -32,6 +33,12 @@ class TestAnalyticsBasic(ModuleStoreTestCase):
self.ces = tuple(CourseEnrollment.enroll(user, self.course_key)
for user in self.users)
self.instructor = InstructorFactory(course_key=self.course_key)
for user in self.users:
user.profile.meta = json.dumps({
"position": "edX expert {}".format(user.id),
"company": "Open edX Inc {}".format(user.id),
})
user.profile.save()
def test_enrolled_students_features_username(self):
self.assertIn('username', AVAILABLE_FEATURES)
......@@ -54,6 +61,19 @@ class TestAnalyticsBasic(ModuleStoreTestCase):
self.assertIn(userreport['email'], [user.email for user in self.users])
self.assertIn(userreport['name'], [user.profile.name for user in self.users])
def test_enrolled_students_meta_features_keys(self):
"""
Assert that we can query individual fields in the 'meta' field in the UserProfile
"""
query_features = ('meta.position', 'meta.company')
with self.assertNumQueries(1):
userreports = enrolled_students_features(self.course_key, query_features)
self.assertEqual(len(userreports), len(self.users))
for userreport in userreports:
self.assertEqual(set(userreport.keys()), set(query_features))
self.assertIn(userreport['meta.position'], ["edX expert {}".format(user.id) for user in self.users])
self.assertIn(userreport['meta.company'], ["Open edX Inc {}".format(user.id) for user in self.users])
def test_enrolled_students_features_keys_cohorted(self):
course = CourseFactory.create(course_key=self.course_key)
course.cohort_config = {'cohorted': True, 'auto_cohort': True, 'auto_cohort_groups': ['cohort']}
......
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