Python django.db.models.fields.related.RelatedField() Examples

The following are 20 code examples of django.db.models.fields.related.RelatedField(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.db.models.fields.related , or try the search function .
Example #1
Source File: mixins.py    From django-cache-manager with MIT License 6 votes vote down vote up
def invalidate_model_cache(self):
        """
        Invalidate model cache by generating new key for the model.
        """
        logger.info('Invalidating cache for table {0}'.format(self.model._meta.db_table))
        if django.VERSION >= (1, 8):
            related_tables = set(
                [f.related_model._meta.db_table for f in self.model._meta.get_fields()
                 if ((f.one_to_many or f.one_to_one) and f.auto_created)
                 or f.many_to_one or (f.many_to_many and not f.auto_created)])
        else:
            related_tables = set([rel.model._meta.db_table for rel in self.model._meta.get_all_related_objects()])
            # temporary fix for m2m relations with an intermediate model, goes away after better join caching
            related_tables |= set([field.rel.to._meta.db_table for field in self.model._meta.fields if issubclass(type(field), RelatedField)])

        logger.debug('Related tables of model {0} are {1}'.format(self.model, related_tables))
        update_model_cache(self.model._meta.db_table)
        for related_table in related_tables:
            update_model_cache(related_table) 
Example #2
Source File: context.py    From django-stubs with MIT License 6 votes vote down vote up
def get_field_related_model_cls(self, field: Union[RelatedField, ForeignObjectRel]) -> Optional[Type[Model]]:
        if isinstance(field, RelatedField):
            related_model_cls = field.remote_field.model
        else:
            related_model_cls = field.field.model

        if isinstance(related_model_cls, str):
            if related_model_cls == 'self':
                # same model
                related_model_cls = field.model
            elif '.' not in related_model_cls:
                # same file model
                related_model_fullname = field.model.__module__ + '.' + related_model_cls
                related_model_cls = self.get_model_class_by_fullname(related_model_fullname)
            else:
                related_model_cls = self.apps_registry.get_model(related_model_cls)

        return related_model_cls 
Example #3
Source File: feature_field_mixin.py    From urbanfootprint with GNU General Public License v3.0 6 votes vote down vote up
def field_map(path, field_class_path):
        """
            Maps paths to a lambda that converts a value of that path
            to a human readable type. Dates are formatted and
            related objects called object.label
            :param path: The simple or concatinated path to a field
            :param field_class_path: A string representation of the field class
        """
        resolved_field_class = resolve_module_attr(field_class_path)
        if issubclass(resolved_field_class, DateField):
            # Convert to localtime (tzinfo for client will need to be specified in settings or passed from client)
            # We need to convert the timezone offset from [-]HHMM to [-]HH:MM to match javascript's format
            return [path, lambda date: date and re.sub(
                r'(\d{2})(\d{2})$',
                r'\1:\2',
                date.astimezone(tzlocal()).strftime("%Y-%m-%dT%H:%M:%S%z"))
            ]
        if issubclass(resolved_field_class, RelatedField):
            # Insist that the related instances have a label property to present to
            # the user. Use the string format as a last resort
            return [path, FeatureFieldMixin.resolve_instance_label]
        return None 
Example #4
Source File: index.py    From wagtail with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def get_type(self, cls):
        if 'type' in self.kwargs:
            return self.kwargs['type']

        try:
            field = self.get_field(cls)

            # Follow foreign keys to find underlying type
            # We use a while loop as it's possible for a foreign key
            # to target a foreign key in another model.
            # (for example, a foreign key to a child page model will
            # point to the `page_ptr_id` field so we need to follow this
            # second foreign key to find the `id`` field in the Page model)
            while isinstance(field, RelatedField):
                field = field.target_field

            return field.get_internal_type()

        except FieldDoesNotExist:
            return 'CharField' 
Example #5
Source File: context.py    From django-stubs with MIT License 6 votes vote down vote up
def get_field_get_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel], *, method: str) -> MypyType:
        """ Get a type of __get__ for this specific Django field. """
        field_info = helpers.lookup_class_typeinfo(api, field.__class__)
        if field_info is None:
            return AnyType(TypeOfAny.unannotated)

        is_nullable = self.get_field_nullability(field, method)
        if isinstance(field, RelatedField):
            related_model_cls = self.get_field_related_model_cls(field)
            if related_model_cls is None:
                return AnyType(TypeOfAny.from_error)

            if method == 'values':
                primary_key_field = self.get_primary_key_field(related_model_cls)
                return self.get_field_get_type(api, primary_key_field, method=method)

            model_info = helpers.lookup_class_typeinfo(api, related_model_cls)
            if model_info is None:
                return AnyType(TypeOfAny.unannotated)

            return Instance(model_info, [])
        else:
            return helpers.get_private_descriptor_type(field_info, '_pyi_private_get_type',
                                                       is_nullable=is_nullable) 
Example #6
Source File: context.py    From django-stubs with MIT License 6 votes vote down vote up
def get_field_lookup_exact_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel]) -> MypyType:
        if isinstance(field, (RelatedField, ForeignObjectRel)):
            related_model_cls = field.related_model
            primary_key_field = self.get_primary_key_field(related_model_cls)
            primary_key_type = self.get_field_get_type(api, primary_key_field, method='init')

            rel_model_info = helpers.lookup_class_typeinfo(api, related_model_cls)
            if rel_model_info is None:
                return AnyType(TypeOfAny.explicit)

            model_and_primary_key_type = UnionType.make_union([Instance(rel_model_info, []), primary_key_type])
            return helpers.make_optional(model_and_primary_key_type)

        field_info = helpers.lookup_class_typeinfo(api, field.__class__)
        if field_info is None:
            return AnyType(TypeOfAny.explicit)
        return helpers.get_private_descriptor_type(field_info, '_pyi_lookup_exact_type',
                                                   is_nullable=field.null) 
Example #7
Source File: querysets.py    From django-stubs with MIT License 6 votes vote down vote up
def get_field_type_from_lookup(ctx: MethodContext, django_context: DjangoContext, model_cls: Type[Model],
                               *, method: str, lookup: str) -> Optional[MypyType]:
    try:
        lookup_field = django_context.resolve_lookup_into_field(model_cls, lookup)
    except FieldError as exc:
        ctx.api.fail(exc.args[0], ctx.context)
        return None
    except LookupsAreUnsupported:
        return AnyType(TypeOfAny.explicit)

    if ((isinstance(lookup_field, RelatedField) and lookup_field.column == lookup)
            or isinstance(lookup_field, ForeignObjectRel)):
        related_model_cls = django_context.get_field_related_model_cls(lookup_field)
        if related_model_cls is None:
            return AnyType(TypeOfAny.from_error)
        lookup_field = django_context.get_primary_key_field(related_model_cls)

    field_get_type = django_context.get_field_get_type(helpers.get_typechecker_api(ctx),
                                                       lookup_field, method=method)
    return field_get_type 
Example #8
Source File: utils.py    From sal with Apache License 2.0 5 votes vote down vote up
def contains_plural_field(model, fields):
    """ Returns a boolean indicating if ``fields`` contains a relationship to multiple items. """
    source_model = model
    for orm_path in fields:
        model = source_model
        bits = orm_path.lstrip('+-').split('__')
        for bit in bits[:-1]:
            field, _ = get_field(model._meta, bit)
            if isinstance(field, models.ManyToManyField) \
                    or (USE_RELATED_OBJECT and isinstance(field, RelatedObject) and field.field.rel.multiple) \
                    or (not USE_RELATED_OBJECT and isinstance(field, RelatedField) and field.one_to_many):
                return True
            model = get_model_at_related_field(model, bit)
    return False 
Example #9
Source File: compiler.py    From django-postgres-extra with MIT License 5 votes vote down vote up
def _format_field_value(self, field_name) -> str:
        """Formats a field's value for usage in SQL.

        Arguments:
            field_name:
                The name of the field to format
                the value of.

        Returns:
            The field's value formatted for usage
            in SQL.
        """

        field_name = self._normalize_field_name(field_name)
        field = self._get_model_field(field_name)

        value = getattr(self.query.objs[0], field.attname)

        if isinstance(field, RelatedField) and isinstance(value, Model):
            value = value.pk

        return SQLInsertCompiler.prepare_value(
            self,
            field,
            # Note: this deliberately doesn't use `pre_save_val` as we don't
            # want things like auto_now on DateTimeField (etc.) to change the
            # value. We rely on pre_save having already been done by the
            # underlying compiler so that things like FileField have already had
            # the opportunity to save out their data.
            value,
        ) 
Example #10
Source File: helpers.py    From django-stubs with MIT License 5 votes vote down vote up
def get_field_lookup_exact_type(api: TypeChecker, field: Field) -> MypyType:
    if isinstance(field, (RelatedField, ForeignObjectRel)):
        lookup_type_class = field.related_model
        rel_model_info = lookup_class_typeinfo(api, lookup_type_class)
        if rel_model_info is None:
            return AnyType(TypeOfAny.from_error)
        return make_optional(Instance(rel_model_info, []))

    field_info = lookup_class_typeinfo(api, field.__class__)
    if field_info is None:
        return AnyType(TypeOfAny.explicit)
    return get_private_descriptor_type(field_info, '_pyi_lookup_exact_type',
                                       is_nullable=field.null) 
Example #11
Source File: utils.py    From Dailyfresh-B2C with Apache License 2.0 5 votes vote down vote up
def get_field_parts(model, field_name):
    """
    Get the field parts that represent the traversable relationships from the
    base ``model`` to the final field, described by ``field_name``.

    ex::

        >>> parts = get_field_parts(Book, 'author__first_name')
        >>> [p.verbose_name for p in parts]
        ['author', 'first name']

    """
    parts = field_name.split(LOOKUP_SEP)
    opts = model._meta
    fields = []

    # walk relationships
    for name in parts:
        try:
            field = opts.get_field(name)
        except FieldDoesNotExist:
            return None

        fields.append(field)
        if isinstance(field, RelatedField):
            opts = remote_model(field)._meta
        elif isinstance(field, ForeignObjectRel):
            opts = field.related_model._meta

    return fields 
Example #12
Source File: patches.py    From django-more with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_dependencies(self):
        # Generate the default dependencies for a related field
        dependencies = super(DjangoRelatedField, self).get_dependencies()

        if self.remote_field:
            # Account for FKs to swappable models
            swappable_setting = getattr(self, 'swappable_setting', None)
            if swappable_setting is not None:
                dep_app_label = "__setting__"
                dep_object_name = swappable_setting
            else:
                dep_app_label = self.remote_field.model._meta.app_label
                dep_object_name = self.remote_field.model._meta.object_name
            # Depend on the model that this refers to
            dependencies.append(dependency_tuple(
                app_label=dep_app_label,
                object_name=dep_object_name,
                field=None,
                created=True))
            # And any manually declared through model
            if getattr(self.remote_field, 'through', None) and not self.remote_field.through._meta.auto_created:
                dependencies.append(dependency_tuple(
                    app_label=self.remote_field.through._meta.app_label,
                    object_name=self.remote_field.through._meta.object_name,
                    field=None,
                    created=True))
        return dependencies


# Make fields able to declare arbitrary dependencies 
Example #13
Source File: index.py    From wagtail with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def select_on_queryset(self, queryset):
        """
        This method runs either prefetch_related or select_related on the queryset
        to improve indexing speed of the relation.

        It decides which method to call based on the number of related objects:
         - single (eg ForeignKey, OneToOne), it runs select_related
         - multiple (eg ManyToMany, reverse ForeignKey) it runs prefetch_related
        """
        try:
            field = self.get_field(queryset.model)
        except FieldDoesNotExist:
            return queryset

        if isinstance(field, RelatedField) and not isinstance(field, ParentalManyToManyField):
            if field.many_to_one or field.one_to_one:
                queryset = queryset.select_related(self.field_name)
            elif field.one_to_many or field.many_to_many:
                queryset = queryset.prefetch_related(self.field_name)

        elif isinstance(field, ForeignObjectRel):
            # Reverse relation
            if isinstance(field, OneToOneRel):
                # select_related for reverse OneToOneField
                queryset = queryset.select_related(self.field_name)
            else:
                # prefetch_related for anything else (reverse ForeignKey/ManyToManyField)
                queryset = queryset.prefetch_related(self.field_name)

        return queryset 
Example #14
Source File: index.py    From wagtail with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_value(self, obj):
        field = self.get_field(obj.__class__)

        if isinstance(field, (RelatedField, ForeignObjectRel)):
            return getattr(obj, self.field_name) 
Example #15
Source File: index.py    From wagtail with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_value(self, obj):
        from taggit.managers import TaggableManager

        try:
            field = self.get_field(obj.__class__)
            value = field.value_from_object(obj)
            if hasattr(field, 'get_searchable_content'):
                value = field.get_searchable_content(value)
            elif isinstance(field, TaggableManager):
                # As of django-taggit 1.0, value_from_object returns a list of Tag objects,
                # which matches what we want
                pass
            elif isinstance(field, RelatedField):
                # The type of the ForeignKey may have a get_searchable_content method that we should
                # call. Firstly we need to find the field its referencing but it may be referencing
                # another RelatedField (eg an FK to page_ptr_id) so we need to run this in a while
                # loop to find the actual remote field.
                remote_field = field
                while isinstance(remote_field, RelatedField):
                    remote_field = remote_field.target_field

                if hasattr(remote_field, 'get_searchable_content'):
                    value = remote_field.get_searchable_content(value)
            return value
        except FieldDoesNotExist:
            value = getattr(obj, self.field_name, None)
            if hasattr(value, '__call__'):
                value = value()
            return value 
Example #16
Source File: models.py    From django-cache-manager with MIT License 5 votes vote down vote up
def invalidate_model_cache(sender, instance, **kwargs):
    """
    Signal receiver for models to invalidate model cache of sender and related models.
    Model cache is invalidated by generating new key for each model.

    Parameters
    ~~~~~~~~~~
    sender
        The model class
    instance
        The actual instance being saved.
    """
    logger.debug('Received post_save/post_delete signal from sender {0}'.format(sender))
    if django.VERSION >= (1, 8):
        related_tables = set(
            [f.related_model._meta.db_table for f in sender._meta.get_fields()
             if f.related_model is not None
             and (((f.one_to_many or f.one_to_one) and f.auto_created)
                 or f.many_to_one or (f.many_to_many and not f.auto_created))])
    else:
        related_tables = set([rel.model._meta.db_table for rel in sender._meta.get_all_related_objects()])
        # temporary fix for m2m relations with an intermediate model, goes away after better join caching
        related_tables |= set([field.rel.to._meta.db_table for field in sender._meta.fields if issubclass(type(field), RelatedField)])
    logger.debug('Related tables of sender {0} are {1}'.format(sender, related_tables))
    update_model_cache(sender._meta.db_table)
    for related_table in related_tables:
        update_model_cache(related_table) 
Example #17
Source File: base_models.py    From karrot-backend with GNU Affero General Public License v3.0 5 votes vote down vote up
def _get_explicit_field_names(self):
        """
        :rtype: list
        """
        return [
            field.name for field in self._meta.get_fields()
            if isinstance(field, Field) and not isinstance(field, RelatedField)
        ] 
Example #18
Source File: fields.py    From django-stubs with MIT License 4 votes vote down vote up
def fill_descriptor_types_for_related_field(ctx: FunctionContext, django_context: DjangoContext) -> MypyType:
    current_field = _get_current_field_from_assignment(ctx, django_context)
    if current_field is None:
        return AnyType(TypeOfAny.from_error)

    assert isinstance(current_field, RelatedField)

    related_model_cls = django_context.get_field_related_model_cls(current_field)
    if related_model_cls is None:
        return AnyType(TypeOfAny.from_error)

    default_related_field_type = set_descriptor_types_for_field(ctx)

    # self reference with abstract=True on the model where ForeignKey is defined
    current_model_cls = current_field.model
    if (current_model_cls._meta.abstract
            and current_model_cls == related_model_cls):
        # for all derived non-abstract classes, set variable with this name to
        # __get__/__set__ of ForeignKey of derived model
        for model_cls in django_context.all_registered_model_classes:
            if issubclass(model_cls, current_model_cls) and not model_cls._meta.abstract:
                derived_model_info = helpers.lookup_class_typeinfo(helpers.get_typechecker_api(ctx), model_cls)
                if derived_model_info is not None:
                    fk_ref_type = Instance(derived_model_info, [])
                    derived_fk_type = reparametrize_related_field_type(default_related_field_type,
                                                                       set_type=fk_ref_type, get_type=fk_ref_type)
                    helpers.add_new_sym_for_info(derived_model_info,
                                                 name=current_field.name,
                                                 sym_type=derived_fk_type)

    related_model = related_model_cls
    related_model_to_set = related_model_cls
    if related_model_to_set._meta.proxy_for_model is not None:
        related_model_to_set = related_model_to_set._meta.proxy_for_model

    typechecker_api = helpers.get_typechecker_api(ctx)

    related_model_info = helpers.lookup_class_typeinfo(typechecker_api, related_model)
    if related_model_info is None:
        # maybe no type stub
        related_model_type = AnyType(TypeOfAny.unannotated)
    else:
        related_model_type = Instance(related_model_info, [])  # type: ignore

    related_model_to_set_info = helpers.lookup_class_typeinfo(typechecker_api, related_model_to_set)
    if related_model_to_set_info is None:
        # maybe no type stub
        related_model_to_set_type = AnyType(TypeOfAny.unannotated)
    else:
        related_model_to_set_type = Instance(related_model_to_set_info, [])  # type: ignore

    # replace Any with referred_to_type
    return reparametrize_related_field_type(default_related_field_type,
                                            set_type=related_model_to_set_type,
                                            get_type=related_model_type) 
Example #19
Source File: model_utils.py    From urbanfootprint with GNU General Public License v3.0 4 votes vote down vote up
def resolve_field_of_path(manager, field_path, return_related_models=False):
    """
        Resolves a field for a manager and field_path that might have __'s indicating relations
    :param manager:
    :param field_path:
    :param return_related_models
    :return: Either the resolved field, or if return_related_models is True this
    instead returns a tuple of the resolve field and the related model, the latter being non-null
    only for foreign key properties or id properties that represent foreign keys
    (e.g. built_form or built_form_id, respectively, would return the tuple
    (ForeignKey, BuiltForm) or (AutoField, BuiltForm), respectively
    """
    parts = field_path.split('__')
    model = manager.model
    related_model = None
    while len(parts) > 0:
        part = parts.pop(0)
        # Each part either results in a model or field. Field is the end-case
        # Work around Django init bug for dynamic models
        clear_many_cache(model)
        model_or_field_tuple = model._meta._name_map.get(part)
        if not model_or_field_tuple:
            # It might be that the part represents the attname of a field, not the field name
            # This is true for ForeignKey relationships
            # Find the matching field, and if found find the related model's id field
            related_field_tuple = get_value_of_first_matching_key(
                lambda name, field: part == field[0].attname if hasattr(field[0], 'attname') else False,
                model._meta._name_map)
            if related_field_tuple:
                model_or_field_tuple = related_field_tuple[0].rel.to._meta._name_map['id']
                related_model = related_field_tuple[0].rel.to
            if not model_or_field_tuple:
                # Something went wrong, give up
                return None
        if isinstance(model_or_field_tuple[0], RelatedField):
            # RelatedField. Recurse unless we are out of parts of the field_path
            if len(parts) > 0:
                # Continue on
                model = model_or_field_tuple[0].rel.to
                continue
            else:
                related_model = model_or_field_tuple[0].rel.to
        elif isinstance(model_or_field_tuple[0], RelatedObject):
            # RelatedObject. Always recurse
            model = model_or_field_tuple[0].model
            continue

        # RelatedField with no parts left or simple Field type
        return model_or_field_tuple[0] if not return_related_models else\
        (model_or_field_tuple[0], related_model or None) 
Example #20
Source File: main.py    From django-stubs with MIT License 4 votes vote down vote up
def get_additional_deps(self, file: MypyFile) -> List[Tuple[int, str, int]]:
        # for settings
        if file.fullname == 'django.conf' and self.django_context.django_settings_module:
            return [self._new_dependency(self.django_context.django_settings_module)]

        # for values / values_list
        if file.fullname == 'django.db.models':
            return [self._new_dependency('mypy_extensions'), self._new_dependency('typing')]

        # for `get_user_model()`
        if self.django_context.settings:
            if (file.fullname == 'django.contrib.auth'
                    or file.fullname in {'django.http', 'django.http.request'}):
                auth_user_model_name = self.django_context.settings.AUTH_USER_MODEL
                try:
                    auth_user_module = self.django_context.apps_registry.get_model(auth_user_model_name).__module__
                except LookupError:
                    # get_user_model() model app is not installed
                    return []
                return [self._new_dependency(auth_user_module)]

        # ensure that all mentioned to='someapp.SomeModel' are loaded with corresponding related Fields
        defined_model_classes = self.django_context.model_modules.get(file.fullname)
        if not defined_model_classes:
            return []
        deps = set()
        for model_class in defined_model_classes:
            # forward relations
            for field in self.django_context.get_model_fields(model_class):
                if isinstance(field, RelatedField):
                    related_model_cls = self.django_context.get_field_related_model_cls(field)
                    if related_model_cls is None:
                        continue
                    related_model_module = related_model_cls.__module__
                    if related_model_module != file.fullname:
                        deps.add(self._new_dependency(related_model_module))
            # reverse relations
            for relation in model_class._meta.related_objects:
                related_model_cls = self.django_context.get_field_related_model_cls(relation)
                related_model_module = related_model_cls.__module__
                if related_model_module != file.fullname:
                    deps.add(self._new_dependency(related_model_module))
        return list(deps)