diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index 35b3e10640527e59abf630c383d550a81d932946..18acaa2739a9c8534a1f1217b998e9eeadcca2e8 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -213,6 +213,8 @@ class UserProfile(models.Model): Some of the fields are legacy ones that were captured during the initial MITx fall prototype. """ + # cache key format e.g user.<user_id>.profile.country = 'SG' + PROFILE_COUNTRY_CACHE_KEY = u"user.{user_id}.profile.country" class Meta(object): # pylint: disable=missing-docstring db_table = "auth_userprofile" @@ -368,6 +370,29 @@ class UserProfile(models.Model): """ Get the human readable value from an enumerable list of key-value pairs. """ return dict(enumerables)[enum_value] + @classmethod + def country_cache_key_name(cls, user_id): + """Return cache key name to be used to cache current country. + Args: + user_id(int): Id of user. + + Returns: + Unicode cache key + """ + return cls.PROFILE_COUNTRY_CACHE_KEY.format(user_id=user_id) + + +@receiver(models.signals.post_save, sender=UserProfile) +def invalidate_user_profile_country_cache(sender, instance, **kwargs): # pylint: disable=unused-argument, invalid-name + """Invalidate the cache of country in UserProfile model. """ + + changed_fields = getattr(instance, '_changed_fields', {}) + + if 'country' in changed_fields: + cache_key = UserProfile.country_cache_key_name(instance.user_id) + cache.delete(cache_key) + log.info("Country changed in UserProfile for %s, cache deleted", instance.user_id) + @receiver(pre_save, sender=UserProfile) def user_profile_pre_save_callback(sender, **kwargs): diff --git a/common/djangoapps/student/tests/test_user_profile_properties.py b/common/djangoapps/student/tests/test_user_profile_properties.py index 3aac0440893233ad044c2d3d4161cf4148708fbd..06bd37a3a43460335fed6324e03a366cfe372f90 100644 --- a/common/djangoapps/student/tests/test_user_profile_properties.py +++ b/common/djangoapps/student/tests/test_user_profile_properties.py @@ -6,6 +6,7 @@ from django.test import TestCase from student.models import UserProfile from student.tests.factories import UserFactory +from django.core.cache import cache @ddt.ddt @@ -77,3 +78,22 @@ class UserProfilePropertiesTest(TestCase): self._set_gender(None) self.assertIsNone(self.profile.gender_display) + + def test_invalidate_cache_user_profile_country_updated(self): + + country = 'us' + self.profile.country = country + self.profile.save() + + cache_key = UserProfile.country_cache_key_name(self.user.id) + self.assertIsNone(cache.get(cache_key)) + + cache.set(cache_key, self.profile.country) + self.assertEqual(cache.get(cache_key), country) + + country = 'bd' + self.profile.country = country + self.profile.save() + + self.assertNotEqual(cache.get(cache_key), country) + self.assertIsNone(cache.get(cache_key))