Ticket #11226: 11226-r12343.diff
File 11226-r12343.diff, 7.0 KB (added by , 15 years ago) |
---|
-
django/core/management/validation.py
diff --git a/django/core/management/validation.py b/django/core/management/validation.py
a b 175 175 ) 176 176 else: 177 177 seen_intermediary_signatures.append(signature) 178 seen_related_fk, seen_this_fk = False, False 179 for field in f.rel.through._meta.fields: 180 if field.rel: 181 if not seen_related_fk and field.rel.to == f.rel.to: 182 seen_related_fk = True 183 elif field.rel.to == cls: 184 seen_this_fk = True 185 if not seen_related_fk or not seen_this_fk: 186 e.add(opts, "'%s' has a manually-defined m2m relation " 187 "through model %s, which does not have foreign keys " 188 "to %s and %s" % (f.name, f.rel.through._meta.object_name, 189 f.rel.to._meta.object_name, cls._meta.object_name) 190 ) 178 if not f.rel.through._meta.auto_created: 179 seen_related_fk, seen_this_fk = False, False 180 for field in f.rel.through._meta.fields: 181 if field.rel: 182 if not seen_related_fk and field.rel.to == f.rel.to: 183 seen_related_fk = True 184 elif field.rel.to == cls: 185 seen_this_fk = True 186 if not seen_related_fk or not seen_this_fk: 187 e.add(opts, "'%s' is a manually-defined m2m relation " 188 "through model %s, which does not have foreign keys " 189 "to %s and %s" % (f.name, f.rel.through._meta.object_name, 190 f.rel.to._meta.object_name, cls._meta.object_name) 191 ) 191 192 elif isinstance(f.rel.through, basestring): 192 193 e.add(opts, "'%s' specifies an m2m relation through model %s, " 193 194 "which has not been installed" % (f.name, f.rel.through) -
tests/modeltests/invalid_models/models.py
diff --git a/tests/modeltests/invalid_models/models.py b/tests/modeltests/invalid_models/models.py
a b 268 268 invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_4' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_4'. 269 269 invalid_models.missingrelations: 'rel1' has a relation with model Rel1, which has either not been installed or is abstract. 270 270 invalid_models.missingrelations: 'rel2' has an m2m relation with model Rel2, which has either not been installed or is abstract. 271 invalid_models.grouptwo: 'primary' has a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo272 invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo271 invalid_models.grouptwo: 'primary' is a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo 272 invalid_models.grouptwo: 'secondary' is a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo 273 273 invalid_models.missingmanualm2mmodel: 'missing_m2m' specifies an m2m relation through model MissingM2MModel, which has not been installed 274 274 invalid_models.group: The model Group has two manually-defined m2m relations through the model Membership, which is not permitted. Please consider using an extra field on your intermediary model instead. 275 275 invalid_models.group: Intermediary model RelationshipDoubleFK has more than one foreign key to Person, which is ambiguous and is not permitted. -
tests/regressiontests/m2m_regress/models.py
diff --git a/tests/regressiontests/m2m_regress/models.py b/tests/regressiontests/m2m_regress/models.py
a b 1 1 from django.db import models 2 from django.contrib import auth 2 3 3 4 # No related name is needed here, since symmetrical relations are not 4 5 # explicitly reversible. … … 41 42 id = models.CharField(primary_key=True, max_length=100) 42 43 lines = models.ManyToManyField(Line, blank=True, null=True) 43 44 45 # A model with the same name that another one to which it has a m2m relation, 46 # This shouldn't cause a name clash between the automatically created m2m 47 # intermediary table FK field names when running syncdb (#11226) 48 class User(models.Model): 49 name = models.CharField(max_length=30) 50 friends = models.ManyToManyField(auth.models.User) 51 44 52 __test__ = {"regressions": """ 45 53 # Multiple m2m references to the same model or a different model must be 46 54 # distinguished when accessing the relations through an instance attribute. -
django/db/models/fields/related.py
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
a b 511 511 def _add_items(self, source_field_name, target_field_name, *objs): 512 512 # join_table: name of the m2m link table 513 513 # source_field_name: the PK fieldname in join_table for the source object 514 # target_ col_name: the PK fieldname in join_table for the target object514 # target_field_name: the PK fieldname in join_table for the target object 515 515 # *objs - objects to add. Either object instances, or primary keys of object instances. 516 516 517 517 # If there aren't any objects, there is nothing to do. … … 914 914 to_model = field.rel.to 915 915 managed = klass._meta.managed or to_model._meta.managed 916 916 name = '%s_%s' % (klass._meta.object_name, field.name) 917 if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or field.rel.to == klass._meta.object_name:917 if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or to == klass._meta.object_name: 918 918 from_ = 'from_%s' % to.lower() 919 919 to = 'to_%s' % to.lower() 920 920 else: … … 973 973 connection.ops.max_name_length()) 974 974 975 975 def _get_m2m_attr(self, related, attr): 976 "Function that can be curried to provide the source column name for the m2m table"976 "Function that can be curried to provide the source accessor or DB column name for the m2m table" 977 977 cache_attr = '_m2m_%s_cache' % attr 978 978 if hasattr(self, cache_attr): 979 979 return getattr(self, cache_attr) … … 983 983 return getattr(self, cache_attr) 984 984 985 985 def _get_m2m_reverse_attr(self, related, attr): 986 "Function that can be curried to provide the related column name for the m2m table"986 "Function that can be curried to provide the related accessor or DB column name for the m2m table" 987 987 cache_attr = '_m2m_reverse_%s_cache' % attr 988 988 if hasattr(self, cache_attr): 989 989 return getattr(self, cache_attr)