from django.conf import settings


class TenantSyncRouter(object):
    """
    A router to control which applications will be synced,
    depending if we are syncing the shared apps or the tenant apps.
    """

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # the imports below need to be done here else django <1.5 goes crazy
        # https://code.djangoproject.com/ticket/20704
        from django.db import connection
        from django_tenants.utils import get_public_schema_name

        # for INSTALLED_APPS we need a name
        from django.apps import apps
        app_name = apps.get_app_config(app_label).name

        if connection.schema_name == get_public_schema_name():
            if app_name not in settings.SHARED_APPS:
                return False
        else:
            if app_name not in settings.TENANT_APPS:
                return False

        return None

from django.conf import settings
from django.apps import apps as django_apps


class TenantSyncRouter(object):
    """
    A router to control which applications will be synced,
    depending if we are syncing the shared apps or the tenant apps.
    """

    def app_in_list(self, app_label, apps_list):
        """
        Is 'app_label' present in 'apps_list'?

        apps_list is either settings.SHARED_APPS or settings.TENANT_APPS, a
        list of app names.

        We check the presense of the app's name or the full path to the apps's
        AppConfig class.
        https://docs.djangoproject.com/en/1.8/ref/applications/#configuring-applications
        """
        appconfig = django_apps.get_app_config(app_label)
        appconfig_full_name = '{}.{}'.format(
            appconfig.__module__, appconfig.__class__.__name__)
        return (appconfig.name in apps_list) or (appconfig_full_name in apps_list)

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # the imports below need to be done here else django <1.5 goes crazy
        # https://code.djangoproject.com/ticket/20704
        from django.db import connection
        from django_tenants.utils import get_public_schema_name

        if connection.schema_name == get_public_schema_name():
            if not self.app_in_list(app_label, settings.SHARED_APPS):
                return False
        else:
            if not self.app_in_list(app_label, settings.TENANT_APPS):
                return False

        return None

Fix check of an app's presence in INSTALLED_APPS
Fix check of an app's presence in INSTALLED_APPS

In TenantSyncRouter, the logic to check whether an app is a tenant app or shared app was too simplistic. Django 1.7 allows two ways to add an app to INSTALLED_APPS. 1) By specifying the app's name, and 2) By specifying the dotted path to the app's AppConfig's class. This commit ensures that we check for the latter case as well. https://docs.djangoproject.com/en/1.8/ref/applications/#configuring-applications
  from django.conf import settings
+ from django.apps import apps as django_apps
  
  
  class TenantSyncRouter(object):
      """
      A router to control which applications will be synced,
      depending if we are syncing the shared apps or the tenant apps.
      """
  
+     def app_in_list(self, app_label, apps_list):
+         """
+         Is 'app_label' present in 'apps_list'?
+ 
+         apps_list is either settings.SHARED_APPS or settings.TENANT_APPS, a
+         list of app names.
+ 
+         We check the presense of the app's name or the full path to the apps's
+         AppConfig class.
+         https://docs.djangoproject.com/en/1.8/ref/applications/#configuring-applications
+         """
+         appconfig = django_apps.get_app_config(app_label)
+         appconfig_full_name = '{}.{}'.format(
+             appconfig.__module__, appconfig.__class__.__name__)
+         return (appconfig.name in apps_list) or (appconfig_full_name in apps_list)
+ 
      def allow_migrate(self, db, app_label, model_name=None, **hints):
          # the imports below need to be done here else django <1.5 goes crazy
          # https://code.djangoproject.com/ticket/20704
          from django.db import connection
          from django_tenants.utils import get_public_schema_name
  
-         # for INSTALLED_APPS we need a name
-         from django.apps import apps
-         app_name = apps.get_app_config(app_label).name
- 
          if connection.schema_name == get_public_schema_name():
-             if app_name not in settings.SHARED_APPS:
+             if not self.app_in_list(app_label, settings.SHARED_APPS):
                  return False
          else:
-             if app_name not in settings.TENANT_APPS:
+             if not self.app_in_list(app_label, settings.TENANT_APPS):
                  return False
  
          return None
  
Fix check of an app's presence in INSTALLED_APPS
## Code Before:
from django.conf import settings


class TenantSyncRouter(object):
    """
    A router to control which applications will be synced,
    depending if we are syncing the shared apps or the tenant apps.
    """

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # the imports below need to be done here else django <1.5 goes crazy
        # https://code.djangoproject.com/ticket/20704
        from django.db import connection
        from django_tenants.utils import get_public_schema_name

        # for INSTALLED_APPS we need a name
        from django.apps import apps
        app_name = apps.get_app_config(app_label).name

        if connection.schema_name == get_public_schema_name():
            if app_name not in settings.SHARED_APPS:
                return False
        else:
            if app_name not in settings.TENANT_APPS:
                return False

        return None

## Instruction:
Fix check of an app's presence in INSTALLED_APPS
## Code After:
from django.conf import settings
from django.apps import apps as django_apps


class TenantSyncRouter(object):
    """
    A router to control which applications will be synced,
    depending if we are syncing the shared apps or the tenant apps.
    """

    def app_in_list(self, app_label, apps_list):
        """
        Is 'app_label' present in 'apps_list'?

        apps_list is either settings.SHARED_APPS or settings.TENANT_APPS, a
        list of app names.

        We check the presense of the app's name or the full path to the apps's
        AppConfig class.
        https://docs.djangoproject.com/en/1.8/ref/applications/#configuring-applications
        """
        appconfig = django_apps.get_app_config(app_label)
        appconfig_full_name = '{}.{}'.format(
            appconfig.__module__, appconfig.__class__.__name__)
        return (appconfig.name in apps_list) or (appconfig_full_name in apps_list)

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # the imports below need to be done here else django <1.5 goes crazy
        # https://code.djangoproject.com/ticket/20704
        from django.db import connection
        from django_tenants.utils import get_public_schema_name

        if connection.schema_name == get_public_schema_name():
            if not self.app_in_list(app_label, settings.SHARED_APPS):
                return False
        else:
            if not self.app_in_list(app_label, settings.TENANT_APPS):
                return False

        return None
