def get_reverse_path_info(self): opts = self.model._meta from_opts = self.remote_field.model._meta return [ PathInfo(from_opts, opts, (opts.pk, ), self, not self.unique, False) ]
def _get_path_info_with_parent(self): """ Return the path that joins the current model through any parent models. The idea is that if you have a GFK defined on a parent model then we need to join the parent model first, then the child model. """ # With an inheritance chain ChildTag -> Tag and Tag defines the # GenericForeignKey, and a TaggedItem model has a GenericRelation to # ChildTag, then we need to generate a join from TaggedItem to Tag # (as Tag.object_id == TaggedItem.pk), and another join from Tag to # ChildTag (as that is where the relation is to). Do this by first # generating a join to the parent model, then generating joins to the # child models. path = [] opts = self.remote_field.model._meta parent_opts = opts.get_field(self.object_id_field_name).model._meta target = parent_opts.pk path.append( PathInfo(self.model._meta, parent_opts, (target, ), self.remote_field, True, False)) # Collect joins needed for the parent -> child chain. This is easiest # to do if we collect joins for the child -> parent chain and then # reverse the direction (call to reverse() and use of # field.remote_field.get_path_info()). parent_field_chain = [] while parent_opts != opts: field = opts.get_ancestor_link(parent_opts.model) parent_field_chain.append(field) opts = field.remote_field.model._meta parent_field_chain.reverse() for field in parent_field_chain: path.extend(field.remote_field.get_path_info()) return path
def get_path_to_parent(self, parent): """ Return a list of PathInfos containing the path from the current model to the parent model, or an empty list if parent is not a parent of the current model. """ if self.model is parent: return [] # Skip the chain of proxy to the concrete proxied model. proxied_model = self.concrete_model path = [] opts = self for int_model in self.get_base_chain(parent): if int_model is proxied_model: opts = int_model._meta else: final_field = opts.parents[int_model] targets = (final_field.remote_field.get_related_field(),) opts = int_model._meta path.append(PathInfo( from_opts=final_field.model._meta, to_opts=opts, target_fields=targets, join_field=final_field, m2m=False, direct=True, filtered_relation=None, )) return path
def get_path_info(self): opts = self.remote_field.model._meta target = opts.pk return [ PathInfo(self.model._meta, opts, (target, ), self.remote_field, True, False) ]
def get_reverse_path_info(self): to_opts = self.model._meta from_opts = self.remote_field.model._meta return [ PathInfo(from_opts, to_opts, (to_opts.pk, ), self.remote_field, False, False) ]
def get_path_info(self): opts = self.remote_field.model._meta object_id_field = opts.get_field(self.object_id_field_name) if object_id_field.model != opts.model: return self._get_path_info_with_parent() else: target = opts.pk return [PathInfo(self.model._meta, opts, (target,), self.remote_field, True, False)]
def get_reverse_path_info(self, filtered_relation): """ Get path from the related model to this field's model. """ opts = self.model._meta from_opts = self.remote_field.model._meta pathinfos = [PathInfo(from_opts, opts, (from_opts.pk,), self.remote_field, not self.unique, False, filtered_relation)] return pathinfos
def get_path_info(self, filtered_relation=None): """ Get path from this field to the related model. """ opts = self.remote_field.model._meta from_opts = self.model._meta return [ PathInfo(from_opts, opts, self.foreign_related_fields, self, False, True, filtered_relation) ]
def _get_gfk_case_path_info(self, direct=False, filtered_relation=None): pathinfos = [] from_field = self.model._meta.pk opts = self.through._meta linkfield = self.through._meta.get_field(self.m2m_reverse_field_name()) if direct: join1infos = [ PathInfo( self.model._meta, opts, [from_field], self.remote_field, True, False, filtered_relation, ) ] if django.VERSION >= (4, 1) and not filtered_relation: join2infos = linkfield.path_infos else: join2infos = linkfield.get_path_info( filtered_relation=filtered_relation) else: if django.VERSION >= (4, 1) and not filtered_relation: join1infos = linkfield.reverse_path_infos else: join1infos = linkfield.get_reverse_path_info( filtered_relation=filtered_relation) join2infos = [ PathInfo( opts, self.model._meta, [from_field], self, True, False, filtered_relation, ) ] pathinfos.extend(join1infos) pathinfos.extend(join2infos) return pathinfos
def _get_gfk_case_path_info(self, direct=False): pathinfos = [] from_field = self.model._meta.pk opts = self.through._meta linkfield = _get_field(self.through, self.m2m_reverse_field_name()) if direct: join1infos = [ PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False) ] join2infos = linkfield.get_path_info() else: join1infos = linkfield.get_reverse_path_info() join2infos = [ PathInfo(opts, self.model._meta, [from_field], self, True, False) ] pathinfos.extend(join1infos) pathinfos.extend(join2infos) return pathinfos
def get_reverse_path_info(self, filtered_relation=None): opts = self.model._meta from_opts = self.remote_field.model._meta return [PathInfo( from_opts=from_opts, to_opts=opts, target_fields=(opts.pk,), join_field=self, m2m=not self.unique, direct=False, filtered_relation=filtered_relation, )]
def _get_gfk_case_path_info(self, direct=False, filtered_relation=None): pathinfos = [] from_field = self.model._meta.pk opts = self.through._meta linkfield = self.through._meta.get_field(self.m2m_reverse_field_name()) if direct: if VERSION < (2, 0): join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)] join2infos = linkfield.get_path_info() else: join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False, filtered_relation)] join2infos = linkfield.get_path_info(filtered_relation=filtered_relation) else: if VERSION < (2, 0): join1infos = linkfield.get_reverse_path_info() join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False)] else: join1infos = linkfield.get_reverse_path_info(filtered_relation=filtered_relation) join2infos = [PathInfo(opts, self.model._meta, [from_field], self, True, False, filtered_relation)] pathinfos.extend(join1infos) pathinfos.extend(join2infos) return pathinfos
def _get_path_info(self, reverse): pathinfos = [] opts = self.through._meta # this is the src <> through part of the relation, we'll use # path info retrieval functions on this fk_field = opts.get_field(opts._field_names['src']) if reverse: pathinfos.extend(fk_field.get_reverse_path_info()) # through > to part of the relation is generated manually opts = self.model._meta pathinfos.append(PathInfo(self.through._meta, opts, (opts.pk,), self, True, False)) else: # to > through part of the relation is generated manually opts = self.through._meta pathinfos.append(PathInfo(self.model._meta, opts, (opts.pk,), self, False, False)) pathinfos.extend(fk_field.get_path_info()) return pathinfos
def get_path_info(self): """ Django 1.10 will try to resolve InverseRelationship to Relationship; that check is not needed in this case. """ if not hasattr(self, 'remote_field'): return super(GenericRelation, self).get_path_info() opts = self.remote_field.model._meta target = opts.pk return [ PathInfo(self.model._meta, opts, (target, ), self.remote_field, True, False) ]
def get_path_info(self, filtered_relation=None): opts = self.remote_field.model._meta object_id_field = opts.get_field(self.object_id_field_name) if object_id_field.model != opts.model: return self._get_path_info_with_parent(filtered_relation) else: target = opts.pk return [PathInfo( from_opts=self.model._meta, to_opts=opts, target_fields=(target,), join_field=self.remote_field, m2m=True, direct=False, filtered_relation=filtered_relation, )]