Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #7042 -- The management validation command nows alerts users to…

… the

presence (and incorrectness) of unique=True on ManyToManyFields. This has never
worked and generates invalid SQL. Now it's raised as an explicit error during
validation. Thanks to clamothe for the patch.

Still needs a docs change to make this clear, but that goes to the docs
refactor branch.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8488 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 943c28a4c661a76115012dbe1db3e98d7395f1f7 1 parent 0511435
Malcolm Tredinnick authored
9  django/core/management/validation.py
@@ -99,7 +99,7 @@ def get_validation_errors(outfile, app=None):
99 99
                         if r.get_accessor_name() == rel_query_name:
100 100
                             e.add(opts, "Reverse query name for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))
101 101
 
102  
-        seen_intermediary_signatures = [] 
  102
+        seen_intermediary_signatures = []
103 103
         for i, f in enumerate(opts.local_many_to_many):
104 104
             # Check to see if the related m2m field will clash with any
105 105
             # existing fields, m2m fields, m2m related objects or related
@@ -110,6 +110,11 @@ def get_validation_errors(outfile, app=None):
110 110
                 # so skip the next section
111 111
                 if isinstance(f.rel.to, (str, unicode)):
112 112
                     continue
  113
+
  114
+            # Check that the field is not set to unique.  ManyToManyFields do not support unique.
  115
+            if f.unique:
  116
+                e.add(opts, "ManyToManyFields cannot be unique.  Remove the unique argument on '%s'." % f.name)
  117
+
113 118
             if getattr(f.rel, 'through', None) is not None:
114 119
                 if hasattr(f.rel, 'through_model'):
115 120
                     from_model, to_model = cls, f.rel.to
@@ -152,7 +157,7 @@ def get_validation_errors(outfile, app=None):
152 157
                         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, f.rel.to._meta.object_name, cls._meta.object_name))
153 158
                 else:
154 159
                     e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed" % (f.name, f.rel.through))
155  
-            
  160
+
156 161
             rel_opts = f.rel.to._meta
157 162
             rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
158 163
             rel_query_name = f.related_query_name()
11  tests/modeltests/invalid_models/models.py
@@ -110,11 +110,11 @@ class Car(models.Model):
110 110
 class MissingRelations(models.Model):
111 111
     rel1 = models.ForeignKey("Rel1")
112 112
     rel2 = models.ManyToManyField("Rel2")
113  
-    
  113
+
114 114
 class MissingManualM2MModel(models.Model):
115 115
     name = models.CharField(max_length=5)
116 116
     missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
117  
-    
  117
+
118 118
 class Person(models.Model):
119 119
     name = models.CharField(max_length=5)
120 120
 
@@ -176,7 +176,11 @@ class Meta:
176 176
 class AbstractRelationModel(models.Model):
177 177
     fk1 = models.ForeignKey('AbstractModel')
178 178
     fk2 = models.ManyToManyField('AbstractModel')
179  
-    
  179
+
  180
+class UniqueM2M(models.Model):
  181
+    """ Model to test for unique ManyToManyFields, which are invalid. """
  182
+    unique_people = models.ManyToManyField( Person, unique=True )
  183
+
180 184
 model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
181 185
 invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
182 186
 invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
@@ -271,4 +275,5 @@ class AbstractRelationModel(models.Model):
271 275
 invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical.
272 276
 invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract.
273 277
 invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract.
  278
+invalid_models.uniquem2m: ManyToManyFields cannot be unique.  Remove the unique argument on 'unique_people'.
274 279
 """

0 notes on commit 943c28a

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