コード例 #1
0
 def get_concrete_model_key(self, model):
     (
         concrete_models_mapping,
         _,
     ) = self._get_concrete_models_mapping_and_proxy_models()
     model_key = make_model_tuple(model)
     return concrete_models_mapping[model_key]
コード例 #2
0
ファイル: state.py プロジェクト: Hwesta/django
    def __init__(self, real_apps, models, ignore_swappable=False):
        # 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)
        self.real_models = []
        for app_label in real_apps:
            app = global_apps.get_app_config(app_label)
            for model in app.get_models():
                self.real_models.append(ModelState.from_model(model, exclude_rels=True))
        # Populate the app registry with a stub for each application.
        app_labels = {model_state.app_label for model_state in models.values()}
        app_configs = [AppConfigStub(label) for label in sorted(real_apps + list(app_labels))]
        super(StateApps, self).__init__(app_configs)

        # The lock gets in the way of copying as implemented in clone(), which
        # is called whenever Django duplicates a StateApps before updating it.
        self._lock = None

        self.render_multiple(list(models.values()) + self.real_models)

        # There shouldn't be any operations pending at this point.
        from django.core.checks.model_checks import _check_lazy_references
        ignore = {make_model_tuple(settings.AUTH_USER_MODEL)} if ignore_swappable else set()
        errors = _check_lazy_references(self, ignore=ignore)
        if errors:
            raise ValueError("\n".join(error.msg for error in errors))
コード例 #3
0
    def __init__(self, real_apps, models, ignore_swappable=False):
        # 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)
        self.real_models = []
        for app_label in real_apps:
            app = global_apps.get_app_config(app_label)
            for model in app.get_models():
                self.real_models.append(ModelState.from_model(model, exclude_rels=True))
        # Populate the app registry with a stub for each application.
        app_labels = {model_state.app_label for model_state in models.values()}
        app_configs = [AppConfigStub(label) for label in sorted(real_apps + list(app_labels))]
        super(StateApps, self).__init__(app_configs)

        self.render_multiple(list(models.values()) + self.real_models)

        # There shouldn't be any operations pending at this point.
        pending_models = set(self._pending_operations)
        if ignore_swappable:
            pending_models -= {make_model_tuple(settings.AUTH_USER_MODEL)}
        if pending_models:
            msg = "Unhandled pending operations for models: %s"
            labels = (".".join(model_key) for model_key in self._pending_operations)
            raise ValueError(msg % ", ".join(labels))
コード例 #4
0
ファイル: state.py プロジェクト: 317070/django
    def __init__(self, real_apps, models, ignore_swappable=False):
        # 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)
        self.real_models = []
        for app_label in real_apps:
            app = global_apps.get_app_config(app_label)
            for model in app.get_models():
                self.real_models.append(ModelState.from_model(model, exclude_rels=True))
        # Populate the app registry with a stub for each application.
        app_labels = {model_state.app_label for model_state in models.values()}
        app_configs = [AppConfigStub(label) for label in sorted(real_apps + list(app_labels))]
        super(StateApps, self).__init__(app_configs)

        self.render_multiple(list(models.values()) + self.real_models)

        # There shouldn't be any operations pending at this point.
        pending_models = set(self._pending_operations)
        if ignore_swappable:
            pending_models -= {make_model_tuple(settings.AUTH_USER_MODEL)}
        if pending_models:
            msg = "Unhandled pending operations for models: %s"
            labels = (".".join(model_key) for model_key in self._pending_operations)
            raise ValueError(msg % ", ".join(labels))
コード例 #5
0
    def __init__(self,
                 to,
                 max_length=None,
                 min_length=None,
                 strip=True,
                 empty_value='',
                 selector='',
                 **kwargs):
        super().__init__(**kwargs)
        self.selector = selector
        self.to = ''

        try:
            self.to = apps.get_model(*utils.make_model_tuple(to))
        except AttributeError:
            assert isinstance(to, str), (
                "%s(%r) is invalid. First parameter to ForeignField must be "
                "either a model, a model name, or the string %r" % (
                    self.__class__.__name__,
                    to,
                    RECURSIVE_RELATIONSHIP_CONSTANT,
                ))

        self.error_messages['target_exists'] = _('The %s must exist.' %
                                                 self.to.__name__)
        self.error_messages['unique_target'] = _('The %s must be unique.' %
                                                 self.to.__name__)
コード例 #6
0
ファイル: state.py プロジェクト: jebcat1982/django-1
    def __init__(self, real_apps, models, ignore_swappable=False):
        # 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)
        self.real_models = []
        for app_label in real_apps:
            app = global_apps.get_app_config(app_label)
            for model in app.get_models():
                self.real_models.append(
                    ModelState.from_model(model, exclude_rels=True))
        # Populate the app registry with a stub for each application.
        app_labels = {model_state.app_label for model_state in models.values()}
        app_configs = [
            AppConfigStub(label)
            for label in sorted(real_apps + list(app_labels))
        ]
        super().__init__(app_configs)

        # The lock gets in the way of copying as implemented in clone(), which
        # is called whenever Django duplicates a StateApps before updating it.
        self._lock = None

        self.render_multiple(list(models.values()) + self.real_models)

        # There shouldn't be any operations pending at this point.
        from django.core.checks.model_checks import _check_lazy_references
        ignore = {make_model_tuple(settings.AUTH_USER_MODEL)
                  } if ignore_swappable else set()
        errors = _check_lazy_references(self, ignore=ignore)
        if errors:
            raise ValueError("\n".join(error.msg for error in errors))
コード例 #7
0
ファイル: signals.py プロジェクト: EricPengTop/django
 def connect(self, receiver, sender=None, weak=True, dispatch_uid=None, apps=None):
     # Takes a single optional argument named "sender"
     connect = partial(super(ModelSignal, self).connect, receiver, weak=weak, dispatch_uid=dispatch_uid)
     models = [make_model_tuple(sender)] if sender else []
     if not apps:
         from django.db.models.base import Options
         apps = sender._meta.apps if hasattr(sender, '_meta') else Options.default_apps
     apps.lazy_model_operation(connect, *models)
コード例 #8
0
ファイル: state.py プロジェクト: wsqsoft/django-1
 def _find_concrete_model_from_proxy(self, proxy_models, model_state):
     for base in model_state.bases:
         base_key = make_model_tuple(base)
         base_state = proxy_models.get(base_key)
         if not base_state:
             # Concrete model found, stop looking at bases.
             return base_key
         return self._find_concrete_model_from_proxy(proxy_models, base_state)
コード例 #9
0
ファイル: fields.py プロジェクト: peteratfrankl/SHARE
def create_many_to_many_intermediary_model(field, klass):
    from django.db import models

    def set_managed(model, related, through):
        through._meta.managed = model._meta.managed or related._meta.managed

    to_model = resolve_relation(klass, field.remote_field.model)
    name = '%s_%s' % (klass._meta.object_name, field.name)
    lazy_related_operation(set_managed, klass, to_model, name)

    to = make_model_tuple(to_model)[1]
    from_ = klass._meta.model_name
    if to == from_:
        to = 'to_%s' % to
        from_ = 'from_%s' % from_

    meta = type(
        str('Meta'), (object, ), {
            'db_table': field._get_m2m_db_table(klass._meta),
            'auto_created': klass,
            'app_label': klass._meta.app_label,
            'db_tablespace': klass._meta.db_tablespace,
            'unique_together': (from_, to),
            'verbose_name': _('%(from)s-%(to)s relationship') % {
                'from': from_,
                'to': to
            },
            'verbose_name_plural': _('%(from)s-%(to)s relationships') % {
                'from': from_,
                'to': to
            },
            'apps': field.model._meta.apps,
        })
    # Construct and return the new class.
    return type(
        str(name), (models.Model, ), {
            'Meta':
            meta,
            '__module__':
            klass.__module__,
            from_:
            models.ForeignKey(
                klass,
                related_name='%s+' % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                on_delete=DATABASE_CASCADE,
            ),
            to:
            models.ForeignKey(
                to_model,
                related_name='%s+' % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                on_delete=DATABASE_CASCADE,
            )
        })
コード例 #10
0
 def _find_concrete_model_from_proxy(self, proxy_models, model_state):
     for base in model_state.bases:
         if not (isinstance(base, str) or issubclass(base, models.Model)):
             continue
         base_key = make_model_tuple(base)
         base_state = proxy_models.get(base_key)
         if not base_state:
             # Concrete model found, stop looking at bases.
             return base_key
         return self._find_concrete_model_from_proxy(proxy_models, base_state)
コード例 #11
0
ファイル: signals.py プロジェクト: Karnet011/MyRepo
    def _lazy_method(self, method, apps, receiver, sender, **kwargs):
        from django.db.models.options import Options

        # This partial takes a single optional argument named "sender".
        partial_method = partial(method, receiver, **kwargs)
        if isinstance(sender, str):
            apps = apps or Options.default_apps
            apps.lazy_model_operation(partial_method, make_model_tuple(sender))
        else:
            return partial_method(sender)
コード例 #12
0
ファイル: signals.py プロジェクト: 756613351/django
    def _lazy_method(self, method, apps, receiver, sender, **kwargs):
        from django.db.models.options import Options

        # This partial takes a single optional argument named "sender".
        partial_method = partial(method, receiver, **kwargs)
        if isinstance(sender, six.string_types):
            apps = apps or Options.default_apps
            apps.lazy_model_operation(partial_method, make_model_tuple(sender))
        else:
            return partial_method(sender)
コード例 #13
0
ファイル: signals.py プロジェクト: xing-tai/django
 def _lazy_method(self, method, apps, receiver, sender, **kwargs):
     # This partial takes a single optional argument named "sender".
     partial_method = partial(method, receiver, **kwargs)
     # import models here to avoid a circular import
     from django.db import models
     if isinstance(sender, models.Model) or sender is None:
         # Skip lazy_model_operation to get a return value for disconnect()
         return partial_method(sender)
     apps = apps or models.base.Options.default_apps
     apps.lazy_model_operation(partial_method, make_model_tuple(sender))
コード例 #14
0
ファイル: signals.py プロジェクト: Anandnitrate/django
 def _lazy_method(self, method, apps, receiver, sender, **kwargs):
     # This partial takes a single optional argument named "sender".
     partial_method = partial(method, receiver, **kwargs)
     # import models here to avoid a circular import
     from django.db import models
     if isinstance(sender, models.Model) or sender is None:
         # Skip lazy_model_operation to get a return value for disconnect()
         return partial_method(sender)
     apps = apps or models.base.Options.default_apps
     apps.lazy_model_operation(partial_method, make_model_tuple(sender))
コード例 #15
0
def get_allowed_models() -> Tuple[List[str], List[str]]:
    """
    Возвращает два списка моделей, для которых возможна перенарезка:
    список обычных моделей и список галерей.
    """
    regular_models = []
    gallery_models = []
    for app_conf in apps.get_app_configs():
        if app_conf.name == 'paper_uploads':
            continue

        for model in app_conf.get_models():
            if get_allowed_fields(model):
                if is_gallery(model):
                    gallery_models.append(
                        '{}.{}'.format(*make_model_tuple(model)))
                else:
                    regular_models.append(
                        '{}.{}'.format(*make_model_tuple(model)))
    return regular_models, gallery_models
コード例 #16
0
def create_sortable_many_to_many_intermediary_model(field, klass, sort_field_name, base_classes=None):
    def set_managed(model, related, through):
        through._meta.managed = model._meta.managed or related._meta.managed

    to_model = resolve_relation(klass, field.remote_field.model)
    name = '%s_%s' % (klass._meta.object_name, field.name)
    lazy_related_operation(set_managed, klass, to_model, name)
    base_classes = base_classes if base_classes else (models.Model,)

    # TODO : use autoincrement here ?
    sort_field = models.IntegerField(default=0)

    to = make_model_tuple(to_model)[1]
    from_ = klass._meta.model_name
    if to == from_:
        to = 'to_%s' % to
        from_ = 'from_%s' % from_

    meta = type('Meta', (), {
        'db_table': field._get_m2m_db_table(klass._meta),  # pylint: disable=protected-access
        'auto_created': klass,
        'app_label': klass._meta.app_label,
        'db_tablespace': klass._meta.db_tablespace,
        'unique_together': (from_, to),
        'ordering': (sort_field_name,),
        'verbose_name': _('%(from)s-%(to)s relationship') % {'from': from_, 'to': to},
        'verbose_name_plural': _('%(from)s-%(to)s relationships') % {'from': from_, 'to': to},
        'apps': field.model._meta.apps,
    })

    # Construct and return the new class.
    return type(force_str(name), base_classes, {
        'Meta': meta,
        '__module__': klass.__module__,
        from_: models.ForeignKey(
            klass,
            related_name='%s+' % name,
            db_tablespace=field.db_tablespace,
            db_constraint=field.remote_field.db_constraint,
            on_delete=models.CASCADE,
        ),
        to: models.ForeignKey(
            to_model,
            related_name='%s+' % name,
            db_tablespace=field.db_tablespace,
            db_constraint=field.remote_field.db_constraint,
            on_delete=models.CASCADE,
        ),
        # Sort fields
        sort_field_name: sort_field,
        '_sort_field_name': sort_field_name,
    })
コード例 #17
0
 def connect(self,
             receiver,
             sender=None,
             weak=True,
             dispatch_uid=None,
             apps=None):
     # Takes a single optional argument named "sender"
     connect = partial(super(ModelSignal, self).connect,
                       receiver,
                       weak=weak,
                       dispatch_uid=dispatch_uid)
     models = [make_model_tuple(sender)] if sender else []
     if not apps:
         from django.db.models.base import Options
         apps = sender._meta.apps if hasattr(
             sender, '_meta') else Options.default_apps
     apps.lazy_model_operation(connect, *models)
コード例 #18
0
ファイル: fields.py プロジェクト: CenterForOpenScience/SHARE
def create_many_to_many_intermediary_model(field, klass):
    from django.db import models

    def set_managed(model, related, through):
        through._meta.managed = model._meta.managed or related._meta.managed

    to_model = resolve_relation(klass, field.remote_field.model)
    name = '%s_%s' % (klass._meta.object_name, field.name)
    lazy_related_operation(set_managed, klass, to_model, name)

    to = make_model_tuple(to_model)[1]
    from_ = klass._meta.model_name
    if to == from_:
        to = 'to_%s' % to
        from_ = 'from_%s' % from_

    meta = type(str('Meta'), (object,), {
        'db_table': field._get_m2m_db_table(klass._meta),
        'auto_created': klass,
        'app_label': klass._meta.app_label,
        'db_tablespace': klass._meta.db_tablespace,
        'unique_together': (from_, to),
        'verbose_name': _('%(from)s-%(to)s relationship') % {'from': from_, 'to': to},
        'verbose_name_plural': _('%(from)s-%(to)s relationships') % {'from': from_, 'to': to},
        'apps': field.model._meta.apps,
    })
    # Construct and return the new class.
    return type(str(name), (models.Model,), {
        'Meta': meta,
        '__module__': klass.__module__,
        from_: models.ForeignKey(
            klass,
            related_name='%s+' % name,
            db_tablespace=field.db_tablespace,
            db_constraint=field.remote_field.db_constraint,
            on_delete=DATABASE_CASCADE,
        ),
        to: models.ForeignKey(
            to_model,
            related_name='%s+' % name,
            db_tablespace=field.db_tablespace,
            db_constraint=field.remote_field.db_constraint,
            on_delete=DATABASE_CASCADE,
        )
    })
コード例 #19
0
ファイル: tasks.py プロジェクト: noviluni/django-bima-core
def rebuild_photo_index(sender_class, instance_id, action_name):
    """
    Given an individual model instance, determine which backends the
    update/update should be sent to & update the object on those backends.
    """
    if action_name not in (
            'update_object',
            'remove_object',
    ):
        logger.error(
            "Action '{}' is not valid operation for haystack index.".format(
                action_name),
            exc_info=True)
        return

    try:
        haystack_signal_processor = apps.get_app_config(
            'haystack').signal_processor
        model = apps.get_model(*make_model_tuple(sender_class))
        instance = _get_instance(model, instance_id)
    except Exception:
        logger.error(
            "An error occurred updating photo index id '{}' with the current haystack application "
            "configuration".format(instance_id),
            extra={
                'sender': sender_class,
                'instance': instance_id
            },
            exc_info=True)
        return

    using_backends = haystack_signal_processor.connection_router.for_write(
        instance=instance)
    for using in using_backends:
        try:
            index = haystack_signal_processor.connections[
                using].get_unified_index().get_index(sender_class)
            getattr(index, action_name)(instance, using=using)
        except NotHandled:
            logger.info(
                "There is not index defined for the sender '{}' class".format(
                    sender_class._meta.label))
コード例 #20
0
    def __new__(mcs, name, bases, attrs):
        from gdpr.loading import purpose_register

        new_class = super().__new__(mcs, name, bases, attrs)
        if hasattr(new_class, 'slug') and new_class.slug:
            if new_class.slug in purpose_register:
                raise ImproperlyConfigured(
                    'More anonymization purposes with slug {}'.format(
                        new_class.slug))

            purpose_register.register(new_class.slug, new_class)

        def set_source_model_class(model):
            new_class.source_model_class = model

        if isinstance(new_class.source_model_class, str):
            apps.lazy_model_operation(
                set_source_model_class,
                make_model_tuple(new_class.source_model_class))

        return new_class
コード例 #21
0
    def _lazy_method(self, method, apps, receiver, sender, **kwargs):
        """
        参数说明:

        method   : 父类中定义的 django.db.models.signals.ModelSignal.connect 方法
        apps     : None
        receiver : 信号接收者,通常是一个可调用对象
        sender   : 信号发送者,可能是一个映射类
        kwargs   : 字典 {'weak': True, 'dispatch_uid': None}
        """
        from django.db.models.options import Options

        # 下面这个偏函数是来自父类 django.dispatch.dispatcher.Signal 的 connect 方法
        # 要调用此偏函数,只需要提供 sender 参数就行了
        partial_method = partial(method, receiver, **kwargs)

        if isinstance(sender, str):
            apps = apps or Options.default_apps
            apps.lazy_model_operation(partial_method, make_model_tuple(sender))
        else:
            # 返回偏函数的调用,也就是调用父类的 connect 方法
            partial_method(sender)
コード例 #22
0
ファイル: fields.py プロジェクト: swisscom/cleanerversion
    def create_versioned_many_to_many_intermediary_model(field, cls,
                                                         field_name):
        # TODO: Verify functionality against
        # django.db.models.fields.related:1048
        # Let's not care too much on what flags could potentially be set on
        #   that intermediary class (e.g. managed, etc)
        # Let's play the game, as if the programmer had specified a class
        #   within his models... Here's how.

        # FIXME: VersionedManyToManyModels do not get registered in the
        #   apps models.
        # FIXME: This is usually done at django/db/models/base.py:284,
        # invoked by create_many_to_many_intermediary_model at
        #   django.db.models.fields.related:1048

        def set_managed(model, related, through):
            through._meta.managed = model._meta.managed or \
                                    related._meta.managed

        to_model = resolve_relation(cls, field.remote_field.model)

        name = '%s_%s' % (cls._meta.object_name, field_name)
        lazy_related_operation(set_managed, cls, to_model, name)

        # Force 'to' to be a string (and leave the hard work to Django)
        to = make_model_tuple(to_model)[1]
        from_ = cls._meta.model_name
        if to == from_:
            from_ = 'from_%s' % from_
            to = 'to_%s' % to

        meta = type('Meta', (object,), {
            'db_table': field._get_m2m_db_table(cls._meta),
            'auto_created': cls,
            'app_label': cls._meta.app_label,
            'db_tablespace': cls._meta.db_tablespace,
            # 'unique_together' is not applicable as is, due to multiple
            #   versions to be allowed to exist.
            # 'unique_together': (from_, to),
            'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_,
                                                              'to': to},
            'verbose_name_plural': '%(from)s-%(to)s relationships' % {
                'from': from_, 'to': to},
            'apps': field.model._meta.apps,
        })
        return type(str(name), (Versionable,), {
            'Meta': meta,
            '__module__': cls.__module__,
            from_: VersionedForeignKey(
                cls,
                related_name='%s+' % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                auto_created=name,
                on_delete=DO_NOTHING,
            ),
            to: VersionedForeignKey(
                to_model,
                related_name='%s+' % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                auto_created=name,
                on_delete=DO_NOTHING,
            ),
        })
コード例 #23
0
    def create_versioned_many_to_many_intermediary_model(
            field, cls, field_name):
        # TODO: Verify functionality against
        # django.db.models.fields.related:1048
        # Let's not care too much on what flags could potentially be set on
        #   that intermediary class (e.g. managed, etc)
        # Let's play the game, as if the programmer had specified a class
        #   within his models... Here's how.

        # FIXME: VersionedManyToManyModels do not get registered in the
        #   apps models.
        # FIXME: This is usually done at django/db/models/base.py:284,
        # invoked by create_many_to_many_intermediary_model at
        #   django.db.models.fields.related:1048

        def set_managed(model, related, through):
            through._meta.managed = model._meta.managed or \
                                    related._meta.managed

        to_model = resolve_relation(cls, field.remote_field.model)

        name = '%s_%s' % (cls._meta.object_name, field_name)
        lazy_related_operation(set_managed, cls, to_model, name)

        # Force 'to' to be a string (and leave the hard work to Django)
        to = make_model_tuple(to_model)[1]
        from_ = cls._meta.model_name
        if to == from_:
            from_ = 'from_%s' % from_
            to = 'to_%s' % to

        meta = type(
            'Meta',
            (object, ),
            {
                'db_table': field._get_m2m_db_table(cls._meta),
                'auto_created': cls,
                'app_label': cls._meta.app_label,
                'db_tablespace': cls._meta.db_tablespace,
                # 'unique_together' is not applicable as is, due to multiple
                #   versions to be allowed to exist.
                # 'unique_together': (from_, to),
                'verbose_name': '%(from)s-%(to)s relationship' % {
                    'from': from_,
                    'to': to
                },
                'verbose_name_plural': '%(from)s-%(to)s relationships' % {
                    'from': from_,
                    'to': to
                },
                'apps': field.model._meta.apps,
            })
        return type(
            str(name), (Versionable, ), {
                'Meta':
                meta,
                '__module__':
                cls.__module__,
                from_:
                VersionedForeignKey(
                    cls,
                    related_name='%s+' % name,
                    db_tablespace=field.db_tablespace,
                    db_constraint=field.remote_field.db_constraint,
                    auto_created=name,
                    on_delete=DO_NOTHING,
                ),
                to:
                VersionedForeignKey(
                    to_model,
                    related_name='%s+' % name,
                    db_tablespace=field.db_tablespace,
                    db_constraint=field.remote_field.db_constraint,
                    auto_created=name,
                    on_delete=DO_NOTHING,
                ),
            })
コード例 #24
0
    def __new__(cls, name, bases, attrs):
        super_new = super(MemModelBase, cls).__new__

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [b for b in bases if isinstance(b, MemModelBase)]
        if not parents:
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, '_meta', None)

        app_label = None

        # Look for an application configuration to attach the model to.
        app_config = apps.get_containing_app_config(module)

        if getattr(meta, 'app_label', None) is None:
            if app_config is None:
                if not abstract:
                    raise RuntimeError(
                        "Model class %s.%s doesn't declare an explicit "
                        "app_label and isn't in an application in "
                        "INSTALLED_APPS." % (module, name))

            else:
                app_label = app_config.label

        new_class.add_to_class('_meta', Options(meta, app_label))
        if not abstract:
            new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    str('DoesNotExist'),
                    tuple(x.DoesNotExist for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (ObjectDoesNotExist, ),
                    module,
                    attached_to=new_class))
            new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    str('MultipleObjectsReturned'),
                    tuple(x.MultipleObjectsReturned for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (MultipleObjectsReturned, ),
                    module,
                    attached_to=new_class))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        if getattr(new_class, '_default_manager', None):
            # Multi-table inheritance doesn't inherit default manager from
            # parents.
            new_class._default_manager = None
            new_class._base_manager = None

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        # All the fields of any type declared on this model
        new_fields = chain(new_class._meta.local_fields,
                           new_class._meta.local_many_to_many,
                           new_class._meta.virtual_fields)
        field_names = {f.name for f in new_fields}

        new_class._meta.concrete_model = new_class

        # Collect the parent links for multi-table inheritance.
        parent_links = {}
        for base in reversed([new_class] + parents):
            # Conceptually equivalent to `if base is Model`.
            if not hasattr(base, '_meta'):
                continue
            # Skip concrete parent classes.
            if base != new_class and not base._meta.abstract:
                continue
            # Locate OneToOneField instances.
            for field in base._meta.local_fields:
                if isinstance(field, OneToOneField):
                    related = resolve_relation(new_class,
                                               field.remote_field.model)
                    parent_links[make_model_tuple(related)] = field
        # Do the appropriate setup for any model parents.
        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                     (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                base = base._meta.concrete_model
                base_key = make_model_tuple(base)
                if base_key in parent_links:
                    field = parent_links[base_key]
                #elif not is_proxy:
                else:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(
                        base,
                        on_delete=CASCADE,
                        name=attr_name,
                        auto_created=True,
                        parent_link=True,
                    )
                    # Only add the ptr field if it's not already present;
                    # e.g. migrations will already have it specified
                    if not hasattr(new_class, attr_name):
                        new_class.add_to_class(attr_name, field)
                new_class._meta.parents[base] = field
            else:
                base_parents = base._meta.parents.copy()

                # .. and abstract ones.
                for field in parent_fields:
                    new_field = copy.deepcopy(field)
                    new_class.add_to_class(field.name, new_field)
                    # Replace parent links defined on this base by the new
                    # field as it will be appropriately resolved if required.
                    if field.one_to_one:
                        for parent, parent_link in base_parents.items():
                            if field == parent_link:
                                base_parents[parent] = new_field

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base_parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'abstract base class %r' %
                                     (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        new_class._meta.apps.register_model(new_class._meta.app_label,
                                            new_class)
        return new_class
コード例 #25
0
def create_sortable_many_to_many_intermediary_model(
    field, klass, sort_field_name, base_classes=None
):
    def set_managed(model, related, through):
        through._meta.managed = model._meta.managed or related._meta.managed

    to_model = resolve_relation(klass, field.remote_field.model)
    name = "%s_%s" % (klass._meta.object_name, field.name)
    lazy_related_operation(set_managed, klass, to_model, name)
    base_classes = base_classes if base_classes else (models.Model,)

    # TODO : use autoincrement here ?
    sort_field = models.IntegerField(default=0)

    to = make_model_tuple(to_model)[1]
    from_ = klass._meta.model_name
    if to == from_:
        to = "to_%s" % to
        from_ = "from_%s" % from_

    meta = type(
        "Meta",
        (),
        {
            "db_table": field._get_m2m_db_table(klass._meta),
            "auto_created": klass,
            "app_label": klass._meta.app_label,
            "db_tablespace": klass._meta.db_tablespace,
            "unique_together": (from_, to),
            "ordering": (sort_field_name,),
            "verbose_name": _("%(from)s-%(to)s relationship") % {"from": from_, "to": to},
            "verbose_name_plural": _("%(from)s-%(to)s relationships")
            % {"from": from_, "to": to},
            "apps": field.model._meta.apps,
        },
    )

    # Construct and return the new class.
    return type(
        force_str(name),
        base_classes,
        {
            "Meta": meta,
            "__module__": klass.__module__,
            from_: models.ForeignKey(
                klass,
                related_name="%s+" % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                on_delete=models.CASCADE,
            ),
            to: models.ForeignKey(
                to_model,
                related_name="%s+" % name,
                db_tablespace=field.db_tablespace,
                db_constraint=field.remote_field.db_constraint,
                on_delete=models.CASCADE,
            ),
            # Sort fields
            sort_field_name: sort_field,
            "_sort_field_name": sort_field_name,
        },
    )
コード例 #26
0
ファイル: base.py プロジェクト: ult-processor/djangotalkto
    def __new__(mcs, name, bases, attrs, **kwargs):
        super_new = super().__new__

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [b for b in bases if isinstance(b, ModelMeta)]
        if not parents:
            return super_new(mcs, name, bases, attrs, **kwargs)

        # Create the class.
        module = attrs.pop('__module__')
        new_attrs = {'__module__': module}
        classcell = attrs.pop('__classcell__', None)
        if classcell is not None:
            new_attrs['__classcell__'] = classcell
        attr_meta = attrs.pop('Meta', None)
        # Pass all attrs without a (Django-specific) contribute_to_class()
        # method to type.__new__() so that they're properly initialized
        # (i.e. __set_name__()).
        contributable_attrs = {}
        for obj_name, obj in list(attrs.items()):
            if _has_contribute_to_class(obj):
                contributable_attrs[obj_name] = obj
            else:
                new_attrs[obj_name] = obj
        new_class = super_new(mcs, name, bases, new_attrs, **kwargs)

        abstract = getattr(attr_meta, 'abstract', False)
        meta = attr_meta or getattr(new_class, 'Meta', None)
        base_meta = getattr(new_class, '_meta', None)

        app_label = None

        new_class.add_to_class('_meta', Options(meta, app_label))
        if not abstract:
            new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    'DoesNotExist',
                    tuple(x.DoesNotExist for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (ObjectDoesNotExist, ),
                    module,
                    attached_to=new_class))
            new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    'MultipleObjectsReturned',
                    tuple(x.MultipleObjectsReturned for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (MultipleObjectsReturned, ),
                    module,
                    attached_to=new_class))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." %
                            (name, base_meta.swapped))

        # Add remaining attributes (those with a contribute_to_class() method)
        # to the class.
        for obj_name, obj in contributable_attrs.items():
            new_class.add_to_class(obj_name, obj)

        # All the fields of any type declared on this model
        new_fields = chain(new_class._meta.local_fields,
                           new_class._meta.local_many_to_many,
                           new_class._meta.private_fields)
        field_names = {f.name for f in new_fields}

        # Basic setup for proxy models.
        new_class._meta.concrete_model = new_class

        # Collect the parent links for multi-table inheritance.
        parent_links = {}
        for base in reversed([new_class] + parents):
            # Conceptually equivalent to `if base is Model`.
            if not hasattr(base, '_meta'):
                continue
            # Skip concrete parent classes.
            if base != new_class and not base._meta.abstract:
                continue
            # Locate OneToOneField instances.
            for field in base._meta.local_fields:
                if isinstance(
                        field,
                        OneToOneField) and field.remote_field.parent_link:
                    related = resolve_relation(new_class,
                                               field.remote_field.model)
                    parent_links[make_model_tuple(related)] = field

        # Track fields inherited from base models.
        inherited_attributes = set()
        # Do the appropriate setup for any model parents.
        for base in new_class.mro():
            if base not in parents or not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                inherited_attributes.update(base.__dict__)
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            if not base._meta.abstract:
                # Check for clashes between locally declared fields and those
                # on the base classes.
                for field in parent_fields:
                    if field.name in field_names:
                        raise FieldError(
                            'Local field %r in class %r clashes with field of '
                            'the same name from base class %r.' % (
                                field.name,
                                name,
                                base.__name__,
                            ))
                    else:
                        inherited_attributes.add(field.name)

                # Concrete classes...
                base = base._meta.concrete_model
                base_key = make_model_tuple(base)
                if base_key in parent_links:
                    field = parent_links[base_key]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(
                        base,
                        on_delete=CASCADE,
                        name=attr_name,
                        auto_created=True,
                        parent_link=True,
                    )

                    if attr_name in field_names:
                        raise FieldError(
                            "Auto-generated field '%s' in class %r for "
                            "parent_link to base class %r clashes with "
                            "declared field of the same name." % (
                                attr_name,
                                name,
                                base.__name__,
                            ))

                    # Only add the ptr field if it's not already present;
                    # e.g. migrations will already have it specified
                    if not hasattr(new_class, attr_name):
                        new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                base_parents = base._meta.parents.copy()

                # Add fields from abstract base class if it wasn't overridden.
                for field in parent_fields:
                    if (field.name not in field_names
                            and field.name not in new_class.__dict__
                            and field.name not in inherited_attributes):
                        new_field = copy.deepcopy(field)
                        new_class.add_to_class(field.name, new_field)
                        # Replace parent links defined on this base by the new
                        # field. It will be appropriately resolved if required.
                        if field.one_to_one:
                            for parent, parent_link in base_parents.items():
                                if field == parent_link:
                                    base_parents[parent] = new_field

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base_parents)

            # Inherit private fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.private_fields:
                if field.name in field_names:
                    if not base._meta.abstract:
                        raise FieldError(
                            'Local field %r in class %r clashes with field of '
                            'the same name from base class %r.' % (
                                field.name,
                                name,
                                base.__name__,
                            ))
                else:
                    field = copy.deepcopy(field)
                    if not base._meta.abstract:
                        field.mti_inherited = True
                    new_class.add_to_class(field.name, field)

        # Copy indexes so that index names are unique when models extend an
        # abstract model.
        new_class._meta.indexes = [
            copy.deepcopy(idx) for idx in new_class._meta.indexes
        ]

        new_class._prepare()
        return new_class
コード例 #27
0
from __future__ import unicode_literals