Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #11226 -- Corrected an validation edge case with m2m relations …

…between two models with the same class name. Thanks to pkoch for the report, and to Ramiro Morales for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12489 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e6db084ac8fdf04ba20b5976a1cebfb77d55c97e 1 parent eb67e44
Russell Keith-Magee authored February 22, 2010
27  django/core/management/validation.py
@@ -179,19 +179,20 @@ def get_validation_errors(outfile, app=None):
179 179
                     )
180 180
                 else:
181 181
                     seen_intermediary_signatures.append(signature)
182  
-                seen_related_fk, seen_this_fk = False, False
183  
-                for field in f.rel.through._meta.fields:
184  
-                    if field.rel:
185  
-                        if not seen_related_fk and field.rel.to == f.rel.to:
186  
-                            seen_related_fk = True
187  
-                        elif field.rel.to == cls:
188  
-                            seen_this_fk = True
189  
-                if not seen_related_fk or not seen_this_fk:
190  
-                    e.add(opts, "'%s' has a manually-defined m2m relation "
191  
-                        "through model %s, which does not have foreign keys "
192  
-                        "to %s and %s" % (f.name, f.rel.through._meta.object_name,
193  
-                            f.rel.to._meta.object_name, cls._meta.object_name)
194  
-                    )
  182
+                if not f.rel.through._meta.auto_created:
  183
+                    seen_related_fk, seen_this_fk = False, False
  184
+                    for field in f.rel.through._meta.fields:
  185
+                        if field.rel:
  186
+                            if not seen_related_fk and field.rel.to == f.rel.to:
  187
+                                seen_related_fk = True
  188
+                            elif field.rel.to == cls:
  189
+                                seen_this_fk = True
  190
+                    if not seen_related_fk or not seen_this_fk:
  191
+                        e.add(opts, "'%s' is a manually-defined m2m relation "
  192
+                            "through model %s, which does not have foreign keys "
  193
+                            "to %s and %s" % (f.name, f.rel.through._meta.object_name,
  194
+                                f.rel.to._meta.object_name, cls._meta.object_name)
  195
+                        )
195 196
             elif isinstance(f.rel.through, basestring):
196 197
                 e.add(opts, "'%s' specifies an m2m relation through model %s, "
197 198
                     "which has not been installed" % (f.name, f.rel.through)
8  django/db/models/fields/related.py
@@ -511,7 +511,7 @@ def get_or_create(self, **kwargs):
@@ -914,7 +914,7 @@ def set_managed(field, model, cls):
@@ -973,7 +973,7 @@ def _get_m2m_db_table(self, opts):
@@ -983,7 +983,7 @@ def _get_m2m_attr(self, related, attr):
4  tests/modeltests/invalid_models/models.py
@@ -268,8 +268,8 @@ class UniqueM2M(models.Model):
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 GroupTwo
272  
-invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo
  271
+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.
9  tests/regressiontests/m2m_regress/models.py
... ...
@@ -1,4 +1,5 @@
1 1
 from django.db import models
  2
+from django.contrib.auth import models as auth
2 3
 
3 4
 # No related name is needed here, since symmetrical relations are not
4 5
 # explicitly reversible.
@@ -41,6 +42,14 @@ class Worksheet(models.Model):
41 42
     id = models.CharField(primary_key=True, max_length=100)
42 43
     lines = models.ManyToManyField(Line, blank=True, null=True)
43 44
 
  45
+# Regression for #11226 -- A model with the same name that another one to
  46
+# which it has a m2m relation. This shouldn't cause a name clash between
  47
+# the automatically created m2m intermediary table FK field names when
  48
+# running syncdb
  49
+class User(models.Model):
  50
+    name = models.CharField(max_length=30)
  51
+    friends = models.ManyToManyField(auth.User)
  52
+
44 53
 __test__ = {"regressions": """
45 54
 # Multiple m2m references to the same model or a different model must be
46 55
 # distinguished when accessing the relations through an instance attribute.

0 notes on commit e6db084

Please sign in to comment.
Something went wrong with that request. Please try again.