Commit cd98dd07 by Clinton Blackburn

Removed Country Model

Given that the domain of countries is well-defined, the iso3166 package is a safe replacement for this data. We no longer need to maintain our own copy of ISO 3166 country codes and names.
parent 1018ced0
...@@ -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 countries single_course_activity problem_response_answer_distribution --database=analytics python manage.py loaddata courses 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
......
...@@ -58,8 +58,11 @@ class Command(BaseCommand): ...@@ -58,8 +58,11 @@ class Command(BaseCommand):
birth_years = dict(zip(birth_years, ratios)) birth_years = dict(zip(birth_years, ratios))
# Delete existing data # Delete existing data
for model in [models.CourseEnrollmentDaily, models.CourseEnrollmentByGender, models.CourseEnrollmentByEducation, for model in [models.CourseEnrollmentDaily,
models.CourseEnrollmentByBirthYear, models.CourseEnrollmentByCountry]: models.CourseEnrollmentByGender,
models.CourseEnrollmentByEducation,
models.CourseEnrollmentByBirthYear,
models.CourseEnrollmentByCountry]:
model.objects.all().delete() model.objects.all().delete()
# Create new data data # Create new data data
...@@ -79,10 +82,10 @@ class Command(BaseCommand): ...@@ -79,10 +82,10 @@ class Command(BaseCommand):
models.CourseEnrollmentByEducation.objects.create(course=course, date=date, count=count, models.CourseEnrollmentByEducation.objects.create(course=course, date=date, count=count,
education_level=education_level) education_level=education_level)
for code, ratio in countries.iteritems(): for country_code, ratio in countries.iteritems():
country = models.Country.objects.get(code=code)
count = int(ratio * daily_total) count = int(ratio * daily_total)
models.CourseEnrollmentByCountry.objects.create(course=course, date=date, count=count, country=country) models.CourseEnrollmentByCountry.objects.create(course=course, date=date, count=count,
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)
......
...@@ -4,8 +4,3 @@ from django.db import models ...@@ -4,8 +4,3 @@ from django.db import models
class CourseManager(models.Manager): class CourseManager(models.Manager):
def get_by_natural_key(self, course_id): def get_by_natural_key(self, course_id):
return self.get(course_id=course_id) return self.get(course_id=course_id)
class CountryManager(models.Manager):
def get_by_natural_key(self, code):
return self.get(code=code)
from collections import namedtuple
from django.db import models from django.db import models
from analytics_data_api.v0.managers import CourseManager, CountryManager from iso3166 import countries
from analytics_data_api.v0.managers import CourseManager
class Course(models.Model): class Course(models.Model):
...@@ -33,10 +35,12 @@ class BaseCourseEnrollment(models.Model): ...@@ -33,10 +35,12 @@ class BaseCourseEnrollment(models.Model):
course = models.ForeignKey(Course, null=False) course = models.ForeignKey(Course, null=False)
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)
class Meta(object): class Meta(object):
abstract = True abstract = True
get_latest_by = 'date' get_latest_by = 'date'
index_together = [('course', 'date',)]
class CourseEnrollmentDaily(BaseCourseEnrollment): class CourseEnrollmentDaily(BaseCourseEnrollment):
...@@ -50,7 +54,7 @@ class CourseEnrollmentByBirthYear(BaseCourseEnrollment): ...@@ -50,7 +54,7 @@ class CourseEnrollmentByBirthYear(BaseCourseEnrollment):
birth_year = models.IntegerField(null=False) birth_year = models.IntegerField(null=False)
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_birth_year' db_table = 'course_enrollment_birth_year_daily'
ordering = ('date', 'course', 'birth_year') ordering = ('date', 'course', 'birth_year')
unique_together = [('course', 'date', 'birth_year')] unique_together = [('course', 'date', 'birth_year')]
...@@ -70,7 +74,7 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment): ...@@ -70,7 +74,7 @@ class CourseEnrollmentByEducation(BaseCourseEnrollment):
education_level = models.ForeignKey(EducationLevel) education_level = models.ForeignKey(EducationLevel)
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_education_level' db_table = 'course_enrollment_education_level_daily'
ordering = ('date', 'course', 'education_level') ordering = ('date', 'course', 'education_level')
unique_together = [('course', 'date', 'education_level')] unique_together = [('course', 'date', 'education_level')]
...@@ -79,7 +83,7 @@ class CourseEnrollmentByGender(BaseCourseEnrollment): ...@@ -79,7 +83,7 @@ class CourseEnrollmentByGender(BaseCourseEnrollment):
gender = models.CharField(max_length=255, null=False) gender = models.CharField(max_length=255, null=False)
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_gender' db_table = 'course_enrollment_gender_daily'
ordering = ('date', 'course', 'gender') ordering = ('date', 'course', 'gender')
unique_together = [('course', 'date', 'gender')] unique_together = [('course', 'date', 'gender')]
...@@ -102,23 +106,18 @@ class ProblemResponseAnswerDistribution(models.Model): ...@@ -102,23 +106,18 @@ class ProblemResponseAnswerDistribution(models.Model):
created = models.DateTimeField(auto_now_add=True, db_column='created') created = models.DateTimeField(auto_now_add=True, db_column='created')
class Country(models.Model): Country = namedtuple('Country', 'name, code')
code = models.CharField(max_length=2, primary_key=True)
name = models.CharField(max_length=255, unique=True, null=False)
objects = CountryManager() # pylint: disable=no-value-for-parameter
class Meta(object):
db_table = 'countries'
def __unicode__(self):
return "{0} - {1}".format(self.code, self.name)
class CourseEnrollmentByCountry(BaseCourseEnrollment): class CourseEnrollmentByCountry(BaseCourseEnrollment):
country = models.ForeignKey(Country, null=False, db_column='country_code') country_code = models.CharField(max_length=255, null=False, db_column='country_code')
@property
def country(self):
country = countries.get(self.country_code)
return Country(country.name, country.alpha2)
class Meta(BaseCourseEnrollment.Meta): class Meta(BaseCourseEnrollment.Meta):
db_table = 'course_enrollment_location' db_table = 'course_enrollment_location_current'
ordering = ('date', 'course', 'country') ordering = ('date', 'course', 'country_code')
unique_together = [('course', 'date', 'country')] unique_together = [('course', 'date', 'country_code')]
...@@ -64,11 +64,9 @@ class CourseEnrollmentDailySerializer(BaseCourseEnrollmentModelSerializer): ...@@ -64,11 +64,9 @@ class CourseEnrollmentDailySerializer(BaseCourseEnrollmentModelSerializer):
fields = ('course_id', 'date', 'count') fields = ('course_id', 'date', 'count')
# pylint: disable=no-value-for-parameter class CountrySerializer(serializers.Serializer):
class CountrySerializer(serializers.ModelSerializer): code = serializers.CharField()
class Meta(object): name = serializers.CharField()
model = models.Country
fields = ('code', 'name')
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
...@@ -79,7 +77,8 @@ class EducationLevelSerializer(serializers.ModelSerializer): ...@@ -79,7 +77,8 @@ class EducationLevelSerializer(serializers.ModelSerializer):
class CourseEnrollmentByCountrySerializer(BaseCourseEnrollmentModelSerializer): class CourseEnrollmentByCountrySerializer(BaseCourseEnrollmentModelSerializer):
country = CountrySerializer() # pylint: disable=unexpected-keyword-arg
country = CountrySerializer(many=False)
class Meta(object): class Meta(object):
model = models.CourseEnrollmentByCountry model = models.CourseEnrollmentByCountry
......
...@@ -3,7 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist ...@@ -3,7 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.test import TestCase from django.test import TestCase
from django_dynamic_fixture import G from django_dynamic_fixture import G
from analytics_data_api.v0.models import Course, Country from analytics_data_api.v0.models import Course
class CourseManagerTests(TestCase): class CourseManagerTests(TestCase):
...@@ -13,12 +13,3 @@ class CourseManagerTests(TestCase): ...@@ -13,12 +13,3 @@ class CourseManagerTests(TestCase):
course = G(Course, course_id=course_id) course = G(Course, course_id=course_id)
self.assertEqual(course, Course.objects.get_by_natural_key(course_id)) self.assertEqual(course, Course.objects.get_by_natural_key(course_id))
class CountryManagerTests(TestCase):
def test_get_by_natural_key(self):
code = 'US'
self.assertRaises(ObjectDoesNotExist, Country.objects.get_by_natural_key, code)
country = G(Country, code=code)
self.assertEqual(country, Country.objects.get_by_natural_key(code))
...@@ -2,22 +2,31 @@ from django.test import TestCase ...@@ -2,22 +2,31 @@ from django.test import TestCase
from django_dynamic_fixture import G from django_dynamic_fixture import G
from analytics_data_api.v0.models import EducationLevel, Country from analytics_data_api.v0 import models
class EducationLevelTests(TestCase): class EducationLevelTests(TestCase):
def test_unicode(self): def test_unicode(self):
short_name = 'high_school' short_name = 'high_school'
name = 'High School' name = 'High School'
education_level = G(EducationLevel, short_name=short_name, name=name) education_level = G(models.EducationLevel, short_name=short_name,
name=name)
self.assertEqual(unicode(education_level), "{0} - {1}".format(short_name, name)) self.assertEqual(unicode(education_level),
"{0} - {1}".format(short_name, name))
class CountryTests(TestCase): class CountryTests(TestCase):
def test_unicode(self): # pylint: disable=no-member
code = 'US' def test_attributes(self):
name = 'United States of America' country = models.Country('Canada', 'CA')
country = G(Country, code=code, name=name) self.assertEqual(country.code, 'CA')
self.assertEqual(country.name, 'Canada')
self.assertEqual(unicode(country), "{0} - {1}".format(code, name))
class CourseEnrollmentByCountryTests(TestCase):
def test_country(self):
country = models.Country('United States', 'US')
instance = G(models.CourseEnrollmentByCountry,
country_code=country.code)
self.assertEqual(instance.country, country)
...@@ -8,6 +8,7 @@ import random ...@@ -8,6 +8,7 @@ import random
from django.conf import settings from django.conf import settings
from django_dynamic_fixture import G from django_dynamic_fixture import G
from iso3166 import countries
import pytz import pytz
from analytics_data_api.v0 import models from analytics_data_api.v0 import models
...@@ -291,6 +292,7 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro ...@@ -291,6 +292,7 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro
model = models.CourseEnrollmentByCountry model = models.CourseEnrollmentByCountry
def get_expected_response(self, *args): def get_expected_response(self, *args):
args = sorted(args, key=lambda item: (item.date, item.course.course_id, item.country.code))
return [ return [
{'course_id': str(ce.course.course_id), 'count': ce.count, 'date': ce.date.strftime(settings.DATE_FORMAT), {'course_id': str(ce.course.course_id), 'count': ce.count, 'date': ce.date.strftime(settings.DATE_FORMAT),
'country': {'code': ce.country.code, 'name': ce.country.name}} for ce in args] 'country': {'code': ce.country.code, 'name': ce.country.name}} for ce in args]
...@@ -299,7 +301,7 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro ...@@ -299,7 +301,7 @@ class CourseEnrollmentByLocationViewTests(TestCaseWithAuthentication, CourseEnro
def setUpClass(cls): def setUpClass(cls):
cls.course = G(models.Course) cls.course = G(models.Course)
cls.date = datetime.date(2014, 1, 1) cls.date = datetime.date(2014, 1, 1)
G(cls.model, course=cls.course, country=G(models.Country), count=455, date=cls.date) cls.country = countries.get('US')
G(cls.model, course=cls.course, country=G(models.Country), count=356, date=cls.date) G(cls.model, course=cls.course, country_code='US', count=455, date=cls.date)
G(cls.model, course=cls.course, country=G(models.Country), count=12, G(cls.model, course=cls.course, country_code='CA', count=356, date=cls.date)
date=cls.date - datetime.timedelta(days=29)) G(cls.model, course=cls.course, country_code='IN', count=12, date=cls.date - datetime.timedelta(days=29))
...@@ -6,3 +6,4 @@ djangorestframework==2.3.5 ...@@ -6,3 +6,4 @@ djangorestframework==2.3.5
ipython==2.1.0 ipython==2.1.0
django-rest-swagger==0.1.14 django-rest-swagger==0.1.14
djangorestframework-csv==1.3.3 djangorestframework-csv==1.3.3
iso3166==0.1
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