Commit fbaef361 by Clinton Blackburn

Removed Course Model

The pipeline does not yet support creating a courses table.
parent cd98dd07
...@@ -50,7 +50,7 @@ syncdb: ...@@ -50,7 +50,7 @@ syncdb:
$(foreach db_name,$(DATABASES),./manage.py syncdb --migrate --noinput --database=$(db_name);) $(foreach db_name,$(DATABASES),./manage.py syncdb --migrate --noinput --database=$(db_name);)
loaddata: syncdb loaddata: syncdb
python manage.py loaddata courses education_levels single_course_activity problem_response_answer_distribution --database=analytics python manage.py loaddata education_levels single_course_activity problem_response_answer_distribution --database=analytics
python manage.py generate_fake_enrollment_data python manage.py generate_fake_enrollment_data
demo: clean requirements loaddata demo: clean requirements loaddata
......
[
{
"pk": 1,
"model": "v0.course",
"fields": {
"course_id": "edX/DemoX/Demo_Course"
}
}
]
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"pk": 40, "pk": 40,
"model": "v0.CourseActivityByWeek", "model": "v0.CourseActivityByWeek",
"fields": { "fields": {
"course": ["edX/DemoX/Demo_Course"], "course_id": "edX/DemoX/Demo_Course",
"interval_start": "2014-05-24T00:00:00Z", "interval_start": "2014-05-24T00:00:00Z",
"activity_type": "posted_forum", "activity_type": "posted_forum",
"count": 100, "count": 100,
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
"pk": 106, "pk": 106,
"model": "v0.CourseActivityByWeek", "model": "v0.CourseActivityByWeek",
"fields": { "fields": {
"course": ["edX/DemoX/Demo_Course"], "course_id": "edX/DemoX/Demo_Course",
"interval_start": "2014-05-24T00:00:00Z", "interval_start": "2014-05-24T00:00:00Z",
"activity_type": "attempted_problem", "activity_type": "attempted_problem",
"count": 200, "count": 200,
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"pk": 201, "pk": 201,
"model": "v0.CourseActivityByWeek", "model": "v0.CourseActivityByWeek",
"fields": { "fields": {
"course": ["edX/DemoX/Demo_Course"], "course_id": "edX/DemoX/Demo_Course",
"interval_start": "2014-05-24T00:00:00Z", "interval_start": "2014-05-24T00:00:00Z",
"activity_type": "any", "activity_type": "any",
"count": 300, "count": 300,
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
"pk": 725, "pk": 725,
"model": "v0.CourseActivityByWeek", "model": "v0.CourseActivityByWeek",
"fields": { "fields": {
"course": ["edX/DemoX/Demo_Course"], "course_id": "edX/DemoX/Demo_Course",
"interval_start": "2014-05-24T00:00:00Z", "interval_start": "2014-05-24T00:00:00Z",
"activity_type": "played_video", "activity_type": "played_video",
"count": 400, "count": 400,
......
# pylint: disable=line-too-long
import datetime import datetime
import random import random
...@@ -23,7 +25,7 @@ class Command(BaseCommand): ...@@ -23,7 +25,7 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
days = 120 days = 120
course = models.Course.objects.first() course_id = 'edX/DemoX/Demo_Course'
start_date = datetime.date(year=2014, month=1, day=1) start_date = datetime.date(year=2014, month=1, day=1)
genders = { genders = {
...@@ -65,29 +67,29 @@ class Command(BaseCommand): ...@@ -65,29 +67,29 @@ class Command(BaseCommand):
models.CourseEnrollmentByCountry]: models.CourseEnrollmentByCountry]:
model.objects.all().delete() model.objects.all().delete()
# Create new data data # Create new data
daily_total = 1500 daily_total = 1500
for i in range(days): for i in range(days):
daily_total = get_count(daily_total) daily_total = get_count(daily_total)
date = start_date + datetime.timedelta(days=i) date = start_date + datetime.timedelta(days=i)
models.CourseEnrollmentDaily.objects.create(course=course, date=date, count=daily_total) models.CourseEnrollmentDaily.objects.create(course_id=course_id, date=date, count=daily_total)
for gender, ratio in genders.iteritems(): for gender, ratio in genders.iteritems():
count = int(ratio * daily_total) count = int(ratio * daily_total)
models.CourseEnrollmentByGender.objects.create(course=course, date=date, count=count, gender=gender) models.CourseEnrollmentByGender.objects.create(course_id=course_id, date=date, count=count, gender=gender)
for short_name, ratio in education_levels.iteritems(): for short_name, ratio in education_levels.iteritems():
education_level = models.EducationLevel.objects.get(short_name=short_name) education_level = models.EducationLevel.objects.get(short_name=short_name)
count = int(ratio * daily_total) count = int(ratio * daily_total)
models.CourseEnrollmentByEducation.objects.create(course=course, date=date, count=count, models.CourseEnrollmentByEducation.objects.create(course_id=course_id, date=date, count=count,
education_level=education_level) education_level=education_level)
for country_code, ratio in countries.iteritems(): for country_code, ratio in countries.iteritems():
count = int(ratio * daily_total) count = int(ratio * daily_total)
models.CourseEnrollmentByCountry.objects.create(course=course, date=date, count=count, models.CourseEnrollmentByCountry.objects.create(course_id=course_id, date=date, count=count,
country_code=country_code) country_code=country_code)
for birth_year, ratio in birth_years.iteritems(): for birth_year, ratio in birth_years.iteritems():
count = int(ratio * daily_total) count = int(ratio * daily_total)
models.CourseEnrollmentByBirthYear.objects.create(course=course, date=date, count=count, models.CourseEnrollmentByBirthYear.objects.create(course_id=course_id, date=date, count=count,
birth_year=birth_year) birth_year=birth_year)
from django.db import models
class CourseManager(models.Manager):
def get_by_natural_key(self, course_id):
return self.get(course_id=course_id)
from collections import namedtuple from collections import namedtuple
from django.db import models from django.db import models
from iso3166 import countries from iso3166 import countries
from analytics_data_api.v0.managers import CourseManager
class Course(models.Model):
course_id = models.CharField(unique=True, max_length=255)
objects = CourseManager() # pylint: disable=no-value-for-parameter
class Meta(object):
db_table = 'courses'
class CourseActivityByWeek(models.Model): class CourseActivityByWeek(models.Model):
...@@ -19,7 +9,7 @@ class CourseActivityByWeek(models.Model): ...@@ -19,7 +9,7 @@ class CourseActivityByWeek(models.Model):
class Meta(object): class Meta(object):
db_table = 'course_activity' db_table = 'course_activity'
course = models.ForeignKey(Course, null=False) course_id = models.CharField(max_length=255)
interval_start = models.DateTimeField() interval_start = models.DateTimeField()
interval_end = models.DateTimeField() interval_end = models.DateTimeField()
activity_type = models.CharField(db_index=True, max_length=255) activity_type = models.CharField(db_index=True, max_length=255)
...@@ -28,11 +18,11 @@ class CourseActivityByWeek(models.Model): ...@@ -28,11 +18,11 @@ class CourseActivityByWeek(models.Model):
@classmethod @classmethod
def get_most_recent(cls, course_id, 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_id=course_id, activity_type=activity_type).latest('interval_end') return cls.objects.filter(course_id=course_id, activity_type=activity_type).latest('interval_end')
class BaseCourseEnrollment(models.Model): class BaseCourseEnrollment(models.Model):
course = models.ForeignKey(Course, null=False) course_id = models.CharField(max_length=255)
date = models.DateField(null=False, db_index=True) date = models.DateField(null=False, db_index=True)
count = models.IntegerField(null=False) count = models.IntegerField(null=False)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
...@@ -40,14 +30,14 @@ class BaseCourseEnrollment(models.Model): ...@@ -40,14 +30,14 @@ class BaseCourseEnrollment(models.Model):
class Meta(object): class Meta(object):
abstract = True abstract = True
get_latest_by = 'date' get_latest_by = 'date'
index_together = [('course', 'date',)] index_together = [('course_id', 'date',)]
class CourseEnrollmentDaily(BaseCourseEnrollment): class CourseEnrollmentDaily(BaseCourseEnrollment):
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_daily' db_table = 'course_enrollment_daily'
ordering = ('date', 'course') ordering = ('date', 'course_id')
unique_together = [('course', 'date',)] unique_together = [('course_id', 'date',)]
class CourseEnrollmentByBirthYear(BaseCourseEnrollment): class CourseEnrollmentByBirthYear(BaseCourseEnrollment):
...@@ -55,8 +45,8 @@ class CourseEnrollmentByBirthYear(BaseCourseEnrollment): ...@@ -55,8 +45,8 @@ class CourseEnrollmentByBirthYear(BaseCourseEnrollment):
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_birth_year_daily' db_table = 'course_enrollment_birth_year_daily'
ordering = ('date', 'course', 'birth_year') ordering = ('date', 'course_id', 'birth_year')
unique_together = [('course', 'date', 'birth_year')] unique_together = [('course_id', 'date', 'birth_year')]
class EducationLevel(models.Model): class EducationLevel(models.Model):
...@@ -75,8 +65,8 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment): ...@@ -75,8 +65,8 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment):
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_education_level_daily' db_table = 'course_enrollment_education_level_daily'
ordering = ('date', 'course', 'education_level') ordering = ('date', 'course_id', 'education_level')
unique_together = [('course', 'date', 'education_level')] unique_together = [('course_id', 'date', 'education_level')]
class CourseEnrollmentByGender(BaseCourseEnrollment): class CourseEnrollmentByGender(BaseCourseEnrollment):
...@@ -84,8 +74,8 @@ class CourseEnrollmentByGender(BaseCourseEnrollment): ...@@ -84,8 +74,8 @@ class CourseEnrollmentByGender(BaseCourseEnrollment):
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_gender_daily' db_table = 'course_enrollment_gender_daily'
ordering = ('date', 'course', 'gender') ordering = ('date', 'course_id', 'gender')
unique_together = [('course', 'date', 'gender')] unique_together = [('course_id', 'date', 'gender')]
class ProblemResponseAnswerDistribution(models.Model): class ProblemResponseAnswerDistribution(models.Model):
...@@ -119,5 +109,5 @@ class CourseEnrollmentByCountry(BaseCourseEnrollment): ...@@ -119,5 +109,5 @@ class CourseEnrollmentByCountry(BaseCourseEnrollment):
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_location_current' db_table = 'course_enrollment_location_current'
ordering = ('date', 'course', 'country_code') ordering = ('date', 'course_id', 'country_code')
unique_together = [('course', 'date', 'country_code')] unique_together = [('course_id', 'date', 'country_code')]
...@@ -3,16 +3,7 @@ from rest_framework import serializers ...@@ -3,16 +3,7 @@ from rest_framework import serializers
from analytics_data_api.v0 import models from analytics_data_api.v0 import models
class CourseIdMixin(object): class CourseActivityByWeekSerializer(serializers.ModelSerializer):
def get_course_id(self, obj):
return obj.course.course_id
class RequiredSerializerMethodField(serializers.SerializerMethodField):
required = True
class CourseActivityByWeekSerializer(serializers.ModelSerializer, CourseIdMixin):
""" """
Representation of CourseActivityByWeek that excludes the id field. Representation of CourseActivityByWeek that excludes the id field.
...@@ -20,8 +11,6 @@ class CourseActivityByWeekSerializer(serializers.ModelSerializer, CourseIdMixin) ...@@ -20,8 +11,6 @@ class CourseActivityByWeekSerializer(serializers.ModelSerializer, CourseIdMixin)
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_id = RequiredSerializerMethodField('get_course_id')
class Meta(object): class Meta(object):
model = models.CourseActivityByWeek model = models.CourseActivityByWeek
fields = ('interval_start', 'interval_end', 'activity_type', 'count', 'course_id') fields = ('interval_start', 'interval_end', 'activity_type', 'count', 'course_id')
...@@ -51,8 +40,7 @@ class ProblemResponseAnswerDistributionSerializer(serializers.ModelSerializer): ...@@ -51,8 +40,7 @@ class ProblemResponseAnswerDistributionSerializer(serializers.ModelSerializer):
) )
class BaseCourseEnrollmentModelSerializer(serializers.ModelSerializer, CourseIdMixin): class BaseCourseEnrollmentModelSerializer(serializers.ModelSerializer):
course_id = RequiredSerializerMethodField('get_course_id')
date = serializers.DateField(format=settings.DATE_FORMAT) date = serializers.DateField(format=settings.DATE_FORMAT)
......
from django.core.exceptions import ObjectDoesNotExist
from django.test import TestCase
from django_dynamic_fixture import G
from analytics_data_api.v0.models import Course
class CourseManagerTests(TestCase):
def test_get_by_natural_key(self):
course_id = 'edX/DemoX/Demo_Course'
self.assertRaises(ObjectDoesNotExist, Course.objects.get_by_natural_key, course_id)
course = G(Course, course_id=course_id)
self.assertEqual(course, Course.objects.get_by_natural_key(course_id))
...@@ -5,7 +5,6 @@ from django.core.exceptions import ObjectDoesNotExist ...@@ -5,7 +5,6 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Max from django.db.models import Max
from django.http import Http404 from django.http import Http404
from rest_framework import generics from rest_framework import generics
from rest_framework.generics import get_object_or_404
from analytics_data_api.v0 import models, serializers from analytics_data_api.v0 import models, serializers
...@@ -53,8 +52,11 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView): ...@@ -53,8 +52,11 @@ class CourseActivityMostRecentWeekView(generics.RetrieveAPIView):
class BaseCourseEnrollmentView(generics.ListAPIView): class BaseCourseEnrollmentView(generics.ListAPIView):
def get_course_or_404(self): def verify_course_exists_or_404(self, course_id):
return get_object_or_404(models.Course, course_id=self.kwargs.get('course_id')) if self.model.objects.filter(course_id=course_id).exists():
return True
raise Http404
def apply_date_filtering(self, queryset): def apply_date_filtering(self, queryset):
if 'start_date' in self.request.QUERY_PARAMS or 'end_date' in self.request.QUERY_PARAMS: if 'start_date' in self.request.QUERY_PARAMS or 'end_date' in self.request.QUERY_PARAMS:
...@@ -77,8 +79,9 @@ class BaseCourseEnrollmentView(generics.ListAPIView): ...@@ -77,8 +79,9 @@ class BaseCourseEnrollmentView(generics.ListAPIView):
return queryset return queryset
def get_queryset(self): def get_queryset(self):
course = self.get_course_or_404() course_id = self.kwargs.get('course_id')
queryset = self.model.objects.filter(course=course) self.verify_course_exists_or_404(course_id)
queryset = self.model.objects.filter(course_id=course_id)
queryset = self.apply_date_filtering(queryset) queryset = self.apply_date_filtering(queryset)
return queryset return queryset
...@@ -185,9 +188,4 @@ class CourseEnrollmentByLocationView(BaseCourseEnrollmentView): ...@@ -185,9 +188,4 @@ class CourseEnrollmentByLocationView(BaseCourseEnrollmentView):
""" """
serializer_class = serializers.CourseEnrollmentByCountrySerializer serializer_class = serializers.CourseEnrollmentByCountrySerializer
model = models.CourseEnrollmentByCountry
def get_queryset(self):
course = self.get_course_or_404()
queryset = models.CourseEnrollmentByCountry.objects.filter(course=course)
queryset = self.apply_date_filtering(queryset)
return queryset
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