コード例 #1
0
def create_default_setup_flow(apps: Apps,
                              schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")

    AuthenticatorStaticStage = apps.get_model(
        "authentik_stages_authenticator_static", "AuthenticatorStaticStage")

    db_alias = schema_editor.connection.alias

    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-authenticator-static-setup",
        designation=FlowDesignation.STAGE_CONFIGURATION,
        defaults={
            "name": "default-authenticator-static-setup",
            "title": "Setup Static OTP Tokens",
        },
    )

    stage, _ = AuthenticatorStaticStage.objects.using(
        db_alias).update_or_create(name="default-authenticator-static-setup",
                                   defaults={"token_count": 6})

    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow, stage=stage, defaults={"order": 0})

    for stage in AuthenticatorStaticStage.objects.using(db_alias).filter(
            configure_flow=None):
        stage.configure_flow = flow
        stage.save()
コード例 #2
0
ファイル: 0004_seed.py プロジェクト: omittones/py-learning
def seed(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):

    Song = apps.get_model('playlister', 'Song')
    Playlist = apps.get_model('playlister', 'Playlist')
    PlaylistEntry = apps.get_model('playlister', 'PlaylistEntry')

    db_songs = []
    for i in songs:
        s = Song()
        s.artist = i.get('artist', None)
        s.title = i.get('title', None)
        s.album = 'Uknown'
        s.save()
        db_songs.append(s)

    for i in range(10):
        pl = Playlist()
        pl.name = f'Seeded playlist {i}'
        pl.source = 'USER'
        pl.save()
        for j in range(10):
            pe = PlaylistEntry()
            pe.order = j
            pe.song = choice(db_songs)
            pe.playlist = pl
            pe.save()
コード例 #3
0
def notify_update(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias
    Group = apps.get_model("authentik_core", "Group")
    PolicyBinding = apps.get_model("authentik_policies", "PolicyBinding")
    EventMatcherPolicy = apps.get_model("authentik_policies_event_matcher",
                                        "EventMatcherPolicy")
    NotificationRule = apps.get_model("authentik_events", "NotificationRule")
    NotificationTransport = apps.get_model("authentik_events",
                                           "NotificationTransport")

    admin_group = (Group.objects.using(db_alias).filter(
        name="authentik Admins", is_superuser=True).first())

    policy, _ = EventMatcherPolicy.objects.using(db_alias).update_or_create(
        name="default-match-update",
        defaults={"action": EventAction.UPDATE_AVAILABLE},
    )
    trigger, _ = NotificationRule.objects.using(db_alias).update_or_create(
        name="default-notify-update",
        defaults={
            "group": admin_group,
            "severity": NotificationSeverity.ALERT
        },
    )
    trigger.transports.set(
        NotificationTransport.objects.using(db_alias).filter(
            name="default-email-transport"))
    trigger.save()
    PolicyBinding.objects.using(db_alias).update_or_create(
        target=trigger,
        policy=policy,
        defaults={
            "order": 0,
        },
    )
コード例 #4
0
def create_default_validate_stage(apps: Apps,
                                  schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")
    AuthenticatorValidateStage = apps.get_model(
        "authentik_stages_authenticator_validate",
        "AuthenticatorValidateStage")

    db_alias = schema_editor.connection.alias

    auth_flows = Flow.objects.using(db_alias).filter(
        slug="default-authentication-flow")
    if not auth_flows.exists():
        return

    # If there's already a validation stage in the flow, skip
    if (AuthenticatorValidateStage.objects.using(db_alias).filter(
            flow__slug="default-authentication-flow").exists()):
        return

    validate_stage, _ = AuthenticatorValidateStage.objects.using(
        db_alias).update_or_create(
            name="default-authentication-mfa-validation",
            defaults={
                "device_classes": default_device_classes,
            },
        )

    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=auth_flows.first(),
        stage=validate_stage,
        defaults={
            "order": 30,
        },
    )
コード例 #5
0
def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias
    from django.contrib.sessions.backends.cache import KEY_PREFIX, SessionStore
    from django.core.cache import cache

    AuthenticatedSession = apps.get_model("authentik_core", "AuthenticatedSession")
    User = apps.get_model("authentik_core", "user")

    session_keys = cache.keys(KEY_PREFIX + "*")
    for key in session_keys:
        key = key.replace(KEY_PREFIX, "")
        store = SessionStore(key)
        data = store.load()
        if data == {} or "_auth_user_id" not in data:
            continue
        if (
            AuthenticatedSession.objects.using(db_alias)
            .filter(session_key=key)
            .exists()
        ):
            continue
        users = User.objects.using(db_alias).filter(pk=data.get("_auth_user_id"))
        if not users.exists():
            continue
        AuthenticatedSession.objects.using(db_alias).create(
            session_key=key,
            user=users.first(),
            expires=data.get("_session_expiry", now()),
        )
コード例 #6
0
def create_default_invalidation_flow(apps: Apps,
                                     schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")
    UserLogoutStage = apps.get_model("authentik_stages_user_logout",
                                     "UserLogoutStage")
    db_alias = schema_editor.connection.alias

    UserLogoutStage.objects.using(db_alias).update_or_create(
        name="default-invalidation-logout")

    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-invalidation-flow",
        designation=FlowDesignation.INVALIDATION,
        defaults={
            "name": "Logout",
        },
    )
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow,
        stage=UserLogoutStage.objects.using(db_alias).first(),
        defaults={
            "order": 0,
        },
    )
コード例 #7
0
def create_default_provider_authorization_flow(
        apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")

    ConsentStage = apps.get_model("authentik_stages_consent", "ConsentStage")

    db_alias = schema_editor.connection.alias

    # Empty flow for providers where consent is implicitly given
    Flow.objects.using(db_alias).update_or_create(
        slug="default-provider-authorization-implicit-consent",
        designation=FlowDesignation.AUTHORIZATION,
        defaults={"name": "Authorize Application"},
    )

    # Flow with consent form to obtain explicit user consent
    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-provider-authorization-explicit-consent",
        designation=FlowDesignation.AUTHORIZATION,
        defaults={"name": "Authorize Application"},
    )
    stage, _ = ConsentStage.objects.using(db_alias).update_or_create(
        name="default-provider-authorization-consent")
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow, stage=stage, defaults={"order": 0})
コード例 #8
0
def create_default_authentication_flow(
        apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")
    PasswordStage = apps.get_model("authentik_stages_password",
                                   "PasswordStage")
    UserLoginStage = apps.get_model("authentik_stages_user_login",
                                    "UserLoginStage")
    IdentificationStage = apps.get_model("authentik_stages_identification",
                                         "IdentificationStage")
    db_alias = schema_editor.connection.alias

    identification_stage, _ = IdentificationStage.objects.using(
        db_alias).update_or_create(
            name="default-authentication-identification",
            defaults={
                "user_fields": [UserFields.E_MAIL, UserFields.USERNAME],
            },
        )

    password_stage, _ = PasswordStage.objects.using(db_alias).update_or_create(
        name="default-authentication-password",
        defaults={
            "backends": [BACKEND_INBUILT, BACKEND_LDAP, BACKEND_APP_PASSWORD]
        },
    )

    login_stage, _ = UserLoginStage.objects.using(db_alias).update_or_create(
        name="default-authentication-login")

    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-authentication-flow",
        designation=FlowDesignation.AUTHENTICATION,
        defaults={
            "name": "Welcome to authentik!",
        },
    )
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow,
        stage=identification_stage,
        defaults={
            "order": 10,
        },
    )
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow,
        stage=password_stage,
        defaults={
            "order": 20,
        },
    )
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow,
        stage=login_stage,
        defaults={
            "order": 100,
        },
    )
def assign_sources(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias

    IdentificationStage = apps.get_model("authentik_stages_identification",
                                         "identificationstage")
    Source = apps.get_model("authentik_core", "source")

    sources = Source.objects.all()
    for stage in IdentificationStage.objects.all().using(db_alias):
        stage.sources.set(sources)
        stage.save()
コード例 #10
0
def remove_pb_prefix_users(apps: Apps,
                           schema_editor: BaseDatabaseSchemaEditor):
    alias = schema_editor.connection.alias
    User = apps.get_model("authentik_core", "User")
    Outpost = apps.get_model("authentik_outposts", "Outpost")

    for outpost in Outpost.objects.using(alias).all():
        matching = User.objects.using(alias).filter(
            username=f"pb-outpost-{outpost.uuid.hex}")
        if matching.exists():
            matching.delete()
コード例 #11
0
def migrate_nominations(apps: Apps,
                        schema_editor: BaseDatabaseSchemaEditor) -> None:
    Nomination = apps.get_model("api", "Nomination")
    NominationEntry = apps.get_model("api", "NominationEntry")

    for nomination in Nomination.objects.all():
        nomination_entry = NominationEntry(nomination=nomination,
                                           actor=nomination.actor,
                                           reason=nomination.reason,
                                           inserted_at=nomination.inserted_at)
        nomination_entry.save()
コード例 #12
0
def create_default_password_change(apps: Apps,
                                   schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")

    PromptStage = apps.get_model("authentik_stages_prompt", "PromptStage")
    Prompt = apps.get_model("authentik_stages_prompt", "Prompt")

    UserWriteStage = apps.get_model("authentik_stages_user_write",
                                    "UserWriteStage")

    db_alias = schema_editor.connection.alias

    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-password-change",
        designation=FlowDesignation.STAGE_CONFIGURATION,
        defaults={"name": "Change Password"},
    )

    prompt_stage, _ = PromptStage.objects.using(db_alias).update_or_create(
        name="Change your password", )
    password_prompt, _ = Prompt.objects.using(db_alias).update_or_create(
        field_key="password",
        defaults={
            "label": "Password",
            "type": FieldTypes.PASSWORD,
            "required": True,
            "placeholder": "Password",
            "order": 300,
        },
    )
    password_rep_prompt, _ = Prompt.objects.using(db_alias).update_or_create(
        field_key="password_repeat",
        defaults={
            "label": "Password (repeat)",
            "type": FieldTypes.PASSWORD,
            "required": True,
            "placeholder": "Password (repeat)",
            "order": 301,
        },
    )

    prompt_stage.fields.add(password_prompt)
    prompt_stage.fields.add(password_rep_prompt)
    prompt_stage.save()

    user_write, _ = UserWriteStage.objects.using(db_alias).update_or_create(
        name="default-password-change-write")

    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow, stage=prompt_stage, defaults={"order": 0})
    FlowStageBinding.objects.using(db_alias).update_or_create(
        target=flow, stage=user_write, defaults={"order": 1})
コード例 #13
0
def code(apps: Apps, unused_schema_editor=None):
    """Create the mail templates for all existing events"""
    mailtemplate_class = apps.get_model("invite", "MailTemplate")
    event_class = apps.get_model("invite", "Event")
    subject, text, html = _get_mail_templates()
    for event in event_class.objects.all():
        mailtemplate_class.objects.create(
            event=event,
            subject=subject,
            text=text,
            html=html,
        )
コード例 #14
0
def unmigrate_nominations(apps: Apps,
                          schema_editor: BaseDatabaseSchemaEditor) -> None:
    Nomination = apps.get_model("api", "Nomination")
    NominationEntry = apps.get_model("api", "NominationEntry")

    for entry in NominationEntry.objects.all():
        nomination = Nomination.objects.get(pk=entry.nomination.id)
        nomination.actor = entry.actor
        nomination.reason = entry.reason
        nomination.inserted_at = entry.inserted_at

        nomination.save()
コード例 #15
0
def set_default_group_mappings(apps: Apps, schema_editor):
    LDAPPropertyMapping = apps.get_model("authentik_sources_ldap",
                                         "LDAPPropertyMapping")
    LDAPSource = apps.get_model("authentik_sources_ldap", "LDAPSource")
    db_alias = schema_editor.connection.alias

    for source in LDAPSource.objects.using(db_alias).all():
        if source.property_mappings_group.exists():
            continue
        source.property_mappings_group.set(
            LDAPPropertyMapping.objects.using(db_alias).filter(
                managed="goauthentik.io/sources/ldap/default-name"))
        source.save()
コード例 #16
0
def create_profiles(apps: Apps, schema_editor):
    """
    Create profiles for all the non-discord users
    """
    Profile = apps.get_model("account", "Profile")
    User = apps.get_model(settings.AUTH_USER_MODEL)
    for user in User.objects.all():
        try:
            user.profile
        except Profile.DoesNotExist:
            profile = Profile(
                preferred_username=user.username.replace("#", "."), user=user
            )
            profile.save()
def create_default_admin_group(apps: Apps,
                               schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias
    Group = apps.get_model("authentik_core", "Group")
    User = apps.get_model("authentik_core", "User")

    # Creates a default admin group
    group, _ = Group.objects.using(db_alias).get_or_create(
        is_superuser=True,
        defaults={
            "name": "authentik Admins",
        },
    )
    group.users.set(User.objects.filter(username="******"))
    group.save()
def update_default_source_enrollment_flow_binding(
        apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    FlowStageBinding = apps.get_model("authentik_flows", "FlowStageBinding")
    db_alias = schema_editor.connection.alias

    flows = Flow.objects.using(db_alias).filter(
        slug="default-source-enrollment")
    if not flows.exists():
        return
    flow = flows.first()

    binding = FlowStageBinding.objects.get(target=flow, order=0)
    binding.re_evaluate_policies = True
    binding.save()
コード例 #19
0
def revert_create_group_permission(apps: Apps,
                                   schema_editor: BaseDatabaseSchemaEditor):
    """
    Revert what's done in create_group_permission
    """
    TheGroup: Group = apps.get_model('auth', 'Group')
    ThePermission: Permission = apps.get_model('auth', 'Permission')

    TheGroup.objects.filter(
        name__in=['approved_supervisors', 'course_convener', 'mgt_superusers'
                  ]).delete()

    ThePermission.objects.filter(
        codename__in=['can_convene', 'can_supervise', 'is_mgt_superuser'
                      ]).delete()
コード例 #20
0
ファイル: test_identifier.py プロジェクト: yzgyyang/gitmate-2
    def setUpBeforeMigration(self, apps: Apps):
        Repository = apps.get_model('gitmate_config', 'Repository')
        Installation = apps.get_model('gitmate_config', 'Installation')

        self.inst = Installation(provider='github', identifier=81451)
        self.inst.save()

        self.repo = Repository(provider='github',
                               installation=self.inst,
                               full_name=environ['GITHUB_TEST_REPO'])
        self.repo.save()

        Repository(provider='coala.io',
                   installation=self.inst,
                   full_name='some/fancy/name').save()
コード例 #21
0
def migrate_infractions(apps: Apps,
                        schema_editor: BaseDatabaseSchemaEditor) -> None:
    Infraction = apps.get_model("api", "Infraction")

    for infraction in Infraction.objects.filter(type="voice_ban"):
        infraction.type = "voice_mute"
        infraction.save()
コード例 #22
0
def update_name_temp(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    OAuth2Provider = apps.get_model("authentik_providers_oauth2", "OAuth2Provider")
    db_alias = schema_editor.connection.alias

    for provider in OAuth2Provider.objects.using(db_alias).all():
        provider.name_temp = provider.name
        provider.save()
コード例 #23
0
def revert_create_assessment_templates(
        apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    TheAssessmentTemplate: AssessmentTemplate = apps.get_model(
        'research_mgt', 'AssessmentTemplate')

    TheAssessmentTemplate.objects.filter(
        name__in=['report', 'artifact', 'presentation', 'custom']).delete()
コード例 #24
0
def set_default_token_key(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias
    Token = apps.get_model("authentik_core", "Token")

    for token in Token.objects.using(db_alias).all():
        token.key = token.pk.hex
        token.save()
コード例 #25
0
def set_managed_flag(apps: Apps, schema_editor):
    ScopeMapping = apps.get_model("authentik_providers_oauth2", "ScopeMapping")
    db_alias = schema_editor.connection.alias
    for mapping in ScopeMapping.objects.using(db_alias).filter(
            name__startswith="Autogenerated "):
        mapping.managed = scope_uid_map[mapping.scope_name]
        mapping.save()
コード例 #26
0
def revert_create_courses(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    TheCourse: Course = apps.get_model('research_mgt', 'Course')

    TheCourse.objects.filter(course_number__in=[
        'COMP2710', 'COMP3710', 'COMP3740', 'COMP3770', 'COMP4560', 'COMP6470',
        'COMP8755'
    ]).delete()
コード例 #27
0
def create_default_pre_authentication_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    Flow = apps.get_model("authentik_flows", "Flow")
    SAMLSource = apps.get_model("authentik_sources_saml", "samlsource")

    db_alias = schema_editor.connection.alias

    # Empty flow for providers where consent is implicitly given
    flow, _ = Flow.objects.using(db_alias).update_or_create(
        slug="default-source-pre-authentication",
        designation=FlowDesignation.STAGE_CONFIGURATION,
        defaults={"name": "Pre-Authentication", "title": ""},
    )

    for source in SAMLSource.objects.using(db_alias).all():
        source.pre_authentication_flow = flow
        source.save()
コード例 #28
0
def up(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    cls = apps.get_model('playlister', 'DeezerSettings')
    if not cls.objects.exists():
        row = cls()
        row.id = 1
        row.access_token = None
        row.save()
コード例 #29
0
def remove_profiles(apps: Apps, schema_editor):
    """
    Remove the profiles for all non-discord users
    """
    Profile = apps.get_model("account", "Profile")
    for profile in Profile.objects.all():
        profile.delete()
コード例 #30
0
def migrate_to_username(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias

    UserReputation = apps.get_model("authentik_policies_reputation", "userreputation")
    for rep in UserReputation.objects.using(db_alias).all():
        rep.username = rep.user.username
        rep.save()
コード例 #31
0
ファイル: tests.py プロジェクト: Chukwunonso/django
 def test_dynamic_load(self):
     """
     Makes a new model at runtime and ensures it goes into the right place.
     """
     old_models = apps.get_models(apps.get_app_config("apps").models_module)
     # Construct a new model in a new app registry
     body = {}
     new_apps = Apps()
     meta_contents = {"app_label": "apps", "apps": new_apps}
     meta = type(str("Meta"), tuple(), meta_contents)
     body["Meta"] = meta
     body["__module__"] = TotallyNormal.__module__
     temp_model = type(str("SouthPonies"), (models.Model,), body)
     # Make sure it appeared in the right place!
     self.assertEqual(old_models, apps.get_models(apps.get_app_config("apps").models_module))
     with self.assertRaises(LookupError):
         apps.get_model("apps", "SouthPonies")
     self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model)
コード例 #32
0
ファイル: tests.py プロジェクト: Damgaard/django
 def test_dynamic_load(self):
     """
     Makes a new model at runtime and ensures it goes into the right place.
     """
     old_models = list(apps.get_app_config("apps").get_models())
     # Construct a new model in a new app registry
     body = {}
     new_apps = Apps(["apps"])
     meta_contents = {
         'app_label': "apps",
         'apps': new_apps,
     }
     meta = type("Meta", tuple(), meta_contents)
     body['Meta'] = meta
     body['__module__'] = TotallyNormal.__module__
     temp_model = type("SouthPonies", (models.Model,), body)
     # Make sure it appeared in the right place!
     self.assertEqual(list(apps.get_app_config("apps").get_models()), old_models)
     with self.assertRaises(LookupError):
         apps.get_model("apps", "SouthPonies")
     self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model)
コード例 #33
0
ファイル: state.py プロジェクト: Chwen/django
class ProjectState(object):
    """
    Represents the entire project's overall state.
    This is the item that is passed around - we do it here rather than at the
    app level so that cross-app FKs/etc. resolve properly.
    """

    def __init__(self, models=None, real_apps=None):
        self.models = models or {}
        self.apps = None
        # Apps to include from main registry, usually unmigrated ones
        self.real_apps = real_apps or []

    def add_model_state(self, model_state):
        self.models[(model_state.app_label, model_state.name.lower())] = model_state

    def clone(self):
        "Returns an exact copy of this ProjectState"
        return ProjectState(
            models=dict((k, v.clone()) for k, v in self.models.items()),
            real_apps=self.real_apps,
        )

    def render(self, include_real=None, ignore_swappable=False, skip_cache=False):
        "Turns the project state into actual models in a new Apps"
        if self.apps is None or skip_cache:
            # Any apps in self.real_apps should have all their models included
            # in the render. We don't use the original model instances as there
            # are some variables that refer to the Apps object.
            # FKs/M2Ms from real apps are also not included as they just
            # mess things up with partial states (due to lack of dependencies)
            real_models = []
            for app_label in self.real_apps:
                app = global_apps.get_app_config(app_label)
                for model in app.get_models():
                    real_models.append(ModelState.from_model(model, exclude_rels=True))
            # Populate the app registry with a stub for each application.
            app_labels = set(model_state.app_label for model_state in self.models.values())
            self.apps = Apps([AppConfigStub(label) for label in sorted(self.real_apps + list(app_labels))])
            # We keep trying to render the models in a loop, ignoring invalid
            # base errors, until the size of the unrendered models doesn't
            # decrease by at least one, meaning there's a base dependency loop/
            # missing base.
            unrendered_models = list(self.models.values()) + real_models
            while unrendered_models:
                new_unrendered_models = []
                for model in unrendered_models:
                    try:
                        model.render(self.apps)
                    except InvalidBasesError:
                        new_unrendered_models.append(model)
                if len(new_unrendered_models) == len(unrendered_models):
                    raise InvalidBasesError("Cannot resolve bases for %r\nThis can happen if you are inheriting models from an app with migrations (e.g. contrib.auth)\n in an app with no migrations; see https://docs.djangoproject.com/en/1.7/topics/migrations/#dependencies for more" % new_unrendered_models)
                unrendered_models = new_unrendered_models
            # make sure apps has no dangling references
            if self.apps._pending_lookups:
                # There's some lookups left. See if we can first resolve them
                # ourselves - sometimes fields are added after class_prepared is sent
                for lookup_model, operations in self.apps._pending_lookups.items():
                    try:
                        model = self.apps.get_model(lookup_model[0], lookup_model[1])
                    except LookupError:
                        if "%s.%s" % (lookup_model[0], lookup_model[1]) == settings.AUTH_USER_MODEL and ignore_swappable:
                            continue
                        # Raise an error with a best-effort helpful message
                        # (only for the first issue). Error message should look like:
                        # "ValueError: Lookup failed for model referenced by
                        # field migrations.Book.author: migrations.Author"
                        raise ValueError("Lookup failed for model referenced by field {field}: {model[0]}.{model[1]}".format(
                            field=operations[0][1],
                            model=lookup_model,
                        ))
                    else:
                        do_pending_lookups(model)
        try:
            return self.apps
        finally:
            if skip_cache:
                self.apps = None

    @classmethod
    def from_apps(cls, apps):
        "Takes in an Apps and returns a ProjectState matching it"
        app_models = {}
        for model in apps.get_models(include_swapped=True):
            model_state = ModelState.from_model(model)
            app_models[(model_state.app_label, model_state.name.lower())] = model_state
        return cls(app_models)

    def __eq__(self, other):
        if set(self.models.keys()) != set(other.models.keys()):
            return False
        if set(self.real_apps) != set(other.real_apps):
            return False
        return all(model == other.models[key] for key, model in self.models.items())

    def __ne__(self, other):
        return not (self == other)
コード例 #34
0
ファイル: state.py プロジェクト: hexinH/django
class ProjectState(object):
    """
    Represents the entire project's overall state.
    This is the item that is passed around - we do it here rather than at the
    app level so that cross-app FKs/etc. resolve properly.
    """

    def __init__(self, models=None, real_apps=None):
        self.models = models or {}
        self.apps = None
        # Apps to include from main registry, usually unmigrated ones
        self.real_apps = real_apps or []

    def add_model_state(self, model_state):
        self.models[(model_state.app_label, model_state.name.lower())] = model_state

    def clone(self):
        "Returns an exact copy of this ProjectState"
        return ProjectState(
            models=dict((k, v.clone()) for k, v in self.models.items()),
            real_apps=self.real_apps,
        )

    def render(self, include_real=None):
        "Turns the project state into actual models in a new Apps"
        if self.apps is None:
            # Any apps in self.real_apps should have all their models included
            # in the render. We don't use the original model instances as there
            # are some variables that refer to the Apps object.
            real_models = []
            for app_label in self.real_apps:
                app = global_apps.get_app_config(app_label)
                for model in app.get_models():
                    real_models.append(ModelState.from_model(model))
            # Populate the app registry with a stub for each application.
            app_labels = set(model_state.app_label for model_state in self.models.values())
            self.apps = Apps([AppConfigStub(label) for label in sorted(self.real_apps + list(app_labels))])
            # We keep trying to render the models in a loop, ignoring invalid
            # base errors, until the size of the unrendered models doesn't
            # decrease by at least one, meaning there's a base dependency loop/
            # missing base.
            unrendered_models = list(self.models.values()) + real_models
            while unrendered_models:
                new_unrendered_models = []
                for model in unrendered_models:
                    try:
                        model.render(self.apps)
                    except InvalidBasesError:
                        new_unrendered_models.append(model)
                if len(new_unrendered_models) == len(unrendered_models):
                    raise InvalidBasesError("Cannot resolve bases for %r" % new_unrendered_models)
                unrendered_models = new_unrendered_models
            # make sure apps has no dangling references
            if self.apps._pending_lookups:
                # There's some lookups left. See if we can first resolve them
                # ourselves - sometimes fields are added after class_prepared is sent
                for lookup_model, operations in self.apps._pending_lookups.items():
                    try:
                        model = self.apps.get_model(lookup_model[0], lookup_model[1])
                    except LookupError:
                        # If the lookup failed to something that looks like AUTH_USER_MODEL,
                        # give a better error message about how you can't change it (#22563)
                        extra_message = ""
                        if "%s.%s" % (lookup_model[0], lookup_model[1]) == settings.AUTH_USER_MODEL:
                            extra_message = (
                                "\nThe missing model matches AUTH_USER_MODEL; if you've changed the value of this" +
                                "\nsetting after making a migration, be aware that this is not supported. If you" +
                                "\nchange AUTH_USER_MODEL you must delete and recreate migrations for its app."
                            )
                        # Raise an error with a best-effort helpful message
                        # (only for the first issue). Error message should look like:
                        # "ValueError: Lookup failed for model referenced by
                        # field migrations.Book.author: migrations.Author"
                        raise ValueError("Lookup failed for model referenced by field {field}: {model[0]}.{model[1]}{extra_message}".format(
                            field = operations[0][1],
                            model = lookup_model,
                            extra_message = extra_message,
                        ))
                    else:
                        do_pending_lookups(model)
        return self.apps

    @classmethod
    def from_apps(cls, apps):
        "Takes in an Apps and returns a ProjectState matching it"
        app_models = {}
        for model in apps.get_models():
            model_state = ModelState.from_model(model)
            app_models[(model_state.app_label, model_state.name.lower())] = model_state
        return cls(app_models)

    def __eq__(self, other):
        if set(self.models.keys()) != set(other.models.keys()):
            return False
        if set(self.real_apps) != set(other.real_apps):
            return False
        return all(model == other.models[key] for key, model in self.models.items())

    def __ne__(self, other):
        return not (self == other)