diff --git a/openedx/core/lib/django_courseware_routers.py b/openedx/core/lib/django_courseware_routers.py index af2770e530..52cb384a22 100644 --- a/openedx/core/lib/django_courseware_routers.py +++ b/openedx/core/lib/django_courseware_routers.py @@ -10,20 +10,32 @@ class StudentModuleHistoryExtendedRouter(object): DATABASE_NAME = 'student_module_history' - def _is_csmh(self, model): + def _is_csm(self, model): """ - Return True if ``model`` is courseware.StudentModuleHistoryExtended. + Return True if ``model`` is courseware.models.StudentModule. + """ + return ( + model._meta.app_label == 'courseware' and + type(model).__name__ == 'StudentModule' + ) + + def _is_csm_h(self, model): + """ + Return True if ``model`` is coursewarehistoryextended.models.StudentModuleHistoryExtended. """ return ( model._meta.app_label == 'coursewarehistoryextended' and - model.__name__ == 'StudentModuleHistoryExtended' + ( + type(model).__name__ == 'StudentModuleHistoryExtended' or + getattr(model, '__name__', '') == 'StudentModuleHistoryExtended' + ) ) def db_for_read(self, model, **hints): # pylint: disable=unused-argument """ Use the StudentModuleHistoryExtendedRouter.DATABASE_NAME if the model is StudentModuleHistoryExtended. """ - if self._is_csmh(model): + if self._is_csm_h(model): return self.DATABASE_NAME else: return None @@ -32,16 +44,21 @@ class StudentModuleHistoryExtendedRouter(object): """ Use the StudentModuleHistoryExtendedRouter.DATABASE_NAME if the model is StudentModuleHistoryExtended. """ - if self._is_csmh(model): + if self._is_csm_h(model): return self.DATABASE_NAME else: return None def allow_relation(self, obj1, obj2, **hints): # pylint: disable=unused-argument """ - Disable relations if the model is StudentModuleHistoryExtended. + Manage relations if the model is StudentModuleHistoryExtended. """ - if self._is_csmh(obj1) or self._is_csmh(obj2): + # Allow relation between CSM and CSMH (this cross-database relationship is declared with db_constraint=False). + if self._is_csm(obj1) and self._is_csm_h(obj2): + return True + + # Prevent any other relations with CSMH since CSMH is in its own different database. + elif self._is_csm_h(obj1) or self._is_csm_h(obj2): return False return None @@ -51,7 +68,7 @@ class StudentModuleHistoryExtendedRouter(object): """ if model_name is not None: model = hints.get('model') - if model is not None and self._is_csmh(model): + if model is not None and self._is_csm_h(model): return db == self.DATABASE_NAME if db == self.DATABASE_NAME: return False