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
This commit is contained in:
parent
0511435a33
commit
943c28a4c6
|
@ -99,7 +99,7 @@ def get_validation_errors(outfile, app=None):
|
||||||
if r.get_accessor_name() == rel_query_name:
|
if r.get_accessor_name() == rel_query_name:
|
||||||
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))
|
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))
|
||||||
|
|
||||||
seen_intermediary_signatures = []
|
seen_intermediary_signatures = []
|
||||||
for i, f in enumerate(opts.local_many_to_many):
|
for i, f in enumerate(opts.local_many_to_many):
|
||||||
# Check to see if the related m2m field will clash with any
|
# Check to see if the related m2m field will clash with any
|
||||||
# existing fields, m2m fields, m2m related objects or related
|
# existing fields, m2m fields, m2m related objects or related
|
||||||
|
@ -110,6 +110,11 @@ def get_validation_errors(outfile, app=None):
|
||||||
# so skip the next section
|
# so skip the next section
|
||||||
if isinstance(f.rel.to, (str, unicode)):
|
if isinstance(f.rel.to, (str, unicode)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Check that the field is not set to unique. ManyToManyFields do not support unique.
|
||||||
|
if f.unique:
|
||||||
|
e.add(opts, "ManyToManyFields cannot be unique. Remove the unique argument on '%s'." % f.name)
|
||||||
|
|
||||||
if getattr(f.rel, 'through', None) is not None:
|
if getattr(f.rel, 'through', None) is not None:
|
||||||
if hasattr(f.rel, 'through_model'):
|
if hasattr(f.rel, 'through_model'):
|
||||||
from_model, to_model = cls, f.rel.to
|
from_model, to_model = cls, f.rel.to
|
||||||
|
@ -152,7 +157,7 @@ def get_validation_errors(outfile, app=None):
|
||||||
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))
|
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))
|
||||||
else:
|
else:
|
||||||
e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed" % (f.name, f.rel.through))
|
e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed" % (f.name, f.rel.through))
|
||||||
|
|
||||||
rel_opts = f.rel.to._meta
|
rel_opts = f.rel.to._meta
|
||||||
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
|
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
|
||||||
rel_query_name = f.related_query_name()
|
rel_query_name = f.related_query_name()
|
||||||
|
|
|
@ -110,11 +110,11 @@ class Car(models.Model):
|
||||||
class MissingRelations(models.Model):
|
class MissingRelations(models.Model):
|
||||||
rel1 = models.ForeignKey("Rel1")
|
rel1 = models.ForeignKey("Rel1")
|
||||||
rel2 = models.ManyToManyField("Rel2")
|
rel2 = models.ManyToManyField("Rel2")
|
||||||
|
|
||||||
class MissingManualM2MModel(models.Model):
|
class MissingManualM2MModel(models.Model):
|
||||||
name = models.CharField(max_length=5)
|
name = models.CharField(max_length=5)
|
||||||
missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
|
missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
|
||||||
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(max_length=5)
|
name = models.CharField(max_length=5)
|
||||||
|
|
||||||
|
@ -176,7 +176,11 @@ class AbstractModel(models.Model):
|
||||||
class AbstractRelationModel(models.Model):
|
class AbstractRelationModel(models.Model):
|
||||||
fk1 = models.ForeignKey('AbstractModel')
|
fk1 = models.ForeignKey('AbstractModel')
|
||||||
fk2 = models.ManyToManyField('AbstractModel')
|
fk2 = models.ManyToManyField('AbstractModel')
|
||||||
|
|
||||||
|
class UniqueM2M(models.Model):
|
||||||
|
""" Model to test for unique ManyToManyFields, which are invalid. """
|
||||||
|
unique_people = models.ManyToManyField( Person, unique=True )
|
||||||
|
|
||||||
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
|
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
|
||||||
invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
|
invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
|
||||||
invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
|
invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
|
||||||
|
@ -271,4 +275,5 @@ invalid_models.personselfrefm2m: Intermediary model RelationshipTripleFK has mor
|
||||||
invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical.
|
invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical.
|
||||||
invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract.
|
invalid_models.abstractrelationmodel: 'fk1' has a relation with model AbstractModel, which has either not been installed or is abstract.
|
||||||
invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract.
|
invalid_models.abstractrelationmodel: 'fk2' has an m2m relation with model AbstractModel, which has either not been installed or is abstract.
|
||||||
|
invalid_models.uniquem2m: ManyToManyFields cannot be unique. Remove the unique argument on 'unique_people'.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue