def contribute_to_class(self, cls, name): # Copied to parent, only to change create_many_to_many... to # create_one_to_many.... # To support multiple relations to self, it's useful to have a non-None # related name on symmetrical relations for internal reasons. The # concept doesn't make a lot of sense externally ("you want me to # specify *what* on my non-reversible relation?!"), so we set it up # automatically. The funky name reduces the chance of an accidental # clash. if self.rel.symmetrical and (self.rel.to == "self" or self.rel.to == cls._meta.object_name): self.rel.related_name = "%s_rel_+" % name super(models.ManyToManyField, self).contribute_to_class(cls, name) # The intermediate m2m model is not auto created if: # 1) There is a manually specified intermediate, or # 2) The class owning the m2m field is abstract. if not self.rel.through and not cls._meta.abstract: self.rel.through = create_one_to_many_intermediary_model(self, cls) # Add the descriptor for the m2m relation setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self)) # Set up the accessor for the m2m table name for the relation self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta) # Populate some necessary rel arguments so that cross-app relations # work correctly. if isinstance(self.rel.through, basestring): def resolve_through_model(field, model, cls): field.rel.through = model add_lazy_relation(cls, self, self.rel.through, resolve_through_model) if isinstance(self.rel.to, basestring): target = self.rel.to else: target = self.rel.to._meta.db_table cls._meta.duplicate_targets[self.column] = (target, "m2m")
def contribute_to_related_class(self, cls, related): # Copied from parent, only to change the foreign object descriptor # class. # Internal M2Ms (i.e., those with a related name ending with '+') # don't get a related descriptor. if not self.rel.is_hidden(): setattr(cls, related.get_accessor_name(), RemoteForeignObjectsDescriptor(related)) # Set up the accessors for the column names on the m2m table self.m2m_column_name = curry(self._get_m2m_attr, related, 'column') self.m2m_reverse_name = curry(self._get_m2m_reverse_attr, related, 'column') self.m2m_field_name = curry(self._get_m2m_attr, related, 'name') self.m2m_reverse_field_name = curry(self._get_m2m_reverse_attr, related, 'name') get_m2m_rel = curry(self._get_m2m_attr, related, 'rel') self.m2m_target_field_name = lambda: get_m2m_rel().field_name get_m2m_reverse_rel = curry(self._get_m2m_reverse_attr, related, 'rel') self.m2m_reverse_target_field_name = lambda: get_m2m_reverse_rel().field_name
def contribute_to_related_class(self, cls, related): # Copied from parent, only to change the foreign object descriptor # class. # Internal M2Ms (i.e., those with a related name ending with '+') # don't get a related descriptor. if not self.rel.is_hidden(): setattr(cls, related.get_accessor_name(), RemoteForeignObjectsDescriptor(related)) # Set up the accessors for the column names on the m2m table self.m2m_column_name = curry(self._get_m2m_attr, related, 'column') self.m2m_reverse_name = curry(self._get_m2m_reverse_attr, related, 'column') self.m2m_field_name = curry(self._get_m2m_attr, related, 'name') self.m2m_reverse_field_name = curry(self._get_m2m_reverse_attr, related, 'name') get_m2m_rel = curry(self._get_m2m_attr, related, 'rel') self.m2m_target_field_name = lambda: get_m2m_rel().field_name get_m2m_reverse_rel = curry(self._get_m2m_reverse_attr, related, 'rel') self.m2m_reverse_target_field_name = lambda: get_m2m_reverse_rel( ).field_name