Author: russellm
Date: 2010-02-22 08:04:13 -0600 (Mon, 22 Feb 2010)
New Revision: 12489

Modified:
   django/trunk/django/core/management/validation.py
   django/trunk/django/db/models/fields/related.py
   django/trunk/tests/modeltests/invalid_models/models.py
   django/trunk/tests/regressiontests/m2m_regress/models.py
Log:
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.

Modified: django/trunk/django/core/management/validation.py
===================================================================
--- django/trunk/django/core/management/validation.py   2010-02-22 13:09:02 UTC 
(rev 12488)
+++ django/trunk/django/core/management/validation.py   2010-02-22 14:04:13 UTC 
(rev 12489)
@@ -179,19 +179,20 @@
                     )
                 else:
                     seen_intermediary_signatures.append(signature)
-                seen_related_fk, seen_this_fk = False, False
-                for field in f.rel.through._meta.fields:
-                    if field.rel:
-                        if not seen_related_fk and field.rel.to == f.rel.to:
-                            seen_related_fk = True
-                        elif field.rel.to == cls:
-                            seen_this_fk = True
-                if not seen_related_fk or not seen_this_fk:
-                    e.add(opts, "'%s' has a manually-defined m2m relation "
-                        "through model %s, which does not have foreign keys "
-                        "to %s and %s" % (f.name, 
f.rel.through._meta.object_name,
-                            f.rel.to._meta.object_name, cls._meta.object_name)
-                    )
+                if not f.rel.through._meta.auto_created:
+                    seen_related_fk, seen_this_fk = False, False
+                    for field in f.rel.through._meta.fields:
+                        if field.rel:
+                            if not seen_related_fk and field.rel.to == 
f.rel.to:
+                                seen_related_fk = True
+                            elif field.rel.to == cls:
+                                seen_this_fk = True
+                    if not seen_related_fk or not seen_this_fk:
+                        e.add(opts, "'%s' is a manually-defined m2m relation "
+                            "through model %s, which does not have foreign 
keys "
+                            "to %s and %s" % (f.name, 
f.rel.through._meta.object_name,
+                                f.rel.to._meta.object_name, 
cls._meta.object_name)
+                        )
             elif isinstance(f.rel.through, basestring):
                 e.add(opts, "'%s' specifies an m2m relation through model %s, "
                     "which has not been installed" % (f.name, f.rel.through)

Modified: django/trunk/django/db/models/fields/related.py
===================================================================
--- django/trunk/django/db/models/fields/related.py     2010-02-22 13:09:02 UTC 
(rev 12488)
+++ django/trunk/django/db/models/fields/related.py     2010-02-22 14:04:13 UTC 
(rev 12489)
@@ -511,7 +511,7 @@
         def _add_items(self, source_field_name, target_field_name, *objs):
             # join_table: name of the m2m link table
             # source_field_name: the PK fieldname in join_table for the source 
object
-            # target_col_name: the PK fieldname in join_table for the target 
object
+            # target_field_name: the PK fieldname in join_table for the target 
object
             # *objs - objects to add. Either object instances, or primary keys 
of object instances.
 
             # If there aren't any objects, there is nothing to do.
@@ -914,7 +914,7 @@
         to_model = field.rel.to
         managed = klass._meta.managed or to_model._meta.managed
     name = '%s_%s' % (klass._meta.object_name, field.name)
-    if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or field.rel.to == 
klass._meta.object_name:
+    if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or to == 
klass._meta.object_name:
         from_ = 'from_%s' % to.lower()
         to = 'to_%s' % to.lower()
     else:
@@ -973,7 +973,7 @@
                                       connection.ops.max_name_length())
 
     def _get_m2m_attr(self, related, attr):
-        "Function that can be curried to provide the source column name for 
the m2m table"
+        "Function that can be curried to provide the source accessor or DB 
column name for the m2m table"
         cache_attr = '_m2m_%s_cache' % attr
         if hasattr(self, cache_attr):
             return getattr(self, cache_attr)
@@ -983,7 +983,7 @@
                 return getattr(self, cache_attr)
 
     def _get_m2m_reverse_attr(self, related, attr):
-        "Function that can be curried to provide the related column name for 
the m2m table"
+        "Function that can be curried to provide the related accessor or DB 
column name for the m2m table"
         cache_attr = '_m2m_reverse_%s_cache' % attr
         if hasattr(self, cache_attr):
             return getattr(self, cache_attr)

Modified: django/trunk/tests/modeltests/invalid_models/models.py
===================================================================
--- django/trunk/tests/modeltests/invalid_models/models.py      2010-02-22 
13:09:02 UTC (rev 12488)
+++ django/trunk/tests/modeltests/invalid_models/models.py      2010-02-22 
14:04:13 UTC (rev 12489)
@@ -268,8 +268,8 @@
 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'.
 invalid_models.missingrelations: 'rel1' has a relation with model Rel1, which 
has either not been installed or is abstract.
 invalid_models.missingrelations: 'rel2' has an m2m relation with model Rel2, 
which has either not been installed or is abstract.
-invalid_models.grouptwo: 'primary' has a manually-defined m2m relation through 
model Membership, which does not have foreign keys to Person and GroupTwo
-invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation 
through model MembershipMissingFK, which does not have foreign keys to Group 
and GroupTwo
+invalid_models.grouptwo: 'primary' is a manually-defined m2m relation through 
model Membership, which does not have foreign keys to Person and GroupTwo
+invalid_models.grouptwo: 'secondary' is a manually-defined m2m relation 
through model MembershipMissingFK, which does not have foreign keys to Group 
and GroupTwo
 invalid_models.missingmanualm2mmodel: 'missing_m2m' specifies an m2m relation 
through model MissingM2MModel, which has not been installed
 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.
 invalid_models.group: Intermediary model RelationshipDoubleFK has more than 
one foreign key to Person, which is ambiguous and is not permitted.

Modified: django/trunk/tests/regressiontests/m2m_regress/models.py
===================================================================
--- django/trunk/tests/regressiontests/m2m_regress/models.py    2010-02-22 
13:09:02 UTC (rev 12488)
+++ django/trunk/tests/regressiontests/m2m_regress/models.py    2010-02-22 
14:04:13 UTC (rev 12489)
@@ -1,4 +1,5 @@
 from django.db import models
+from django.contrib.auth import models as auth
 
 # No related name is needed here, since symmetrical relations are not
 # explicitly reversible.
@@ -41,6 +42,14 @@
     id = models.CharField(primary_key=True, max_length=100)
     lines = models.ManyToManyField(Line, blank=True, null=True)
 
+# Regression for #11226 -- A model with the same name that another one to
+# which it has a m2m relation. This shouldn't cause a name clash between
+# the automatically created m2m intermediary table FK field names when
+# running syncdb
+class User(models.Model):
+    name = models.CharField(max_length=30)
+    friends = models.ManyToManyField(auth.User)
+
 __test__ = {"regressions": """
 # Multiple m2m references to the same model or a different model must be
 # distinguished when accessing the relations through an instance attribute.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to