Fixed #3323 -- More robust error handling for related objetcs. Thanks, Greg

Kopka and shaleh.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@6835 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-12-02 18:10:07 +00:00
parent 4ac8ba1855
commit 5e5768ae83
3 changed files with 20 additions and 6 deletions

View File

@ -72,10 +72,14 @@ def get_validation_errors(outfile, app=None):
# Check to see if the related field will clash with any # Check to see if the related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects # existing fields, m2m fields, m2m related objects or related objects
if f.rel: if f.rel:
rel_opts = f.rel.to._meta
if f.rel.to not in models.get_models(): if f.rel.to not in models.get_models():
e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, f.rel.to))
# it is a string and we could not find the model it refers to
# so skip the next section
if isinstance(f.rel.to, (str, unicode)):
continue
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()
for r in rel_opts.fields: for r in rel_opts.fields:
@ -103,10 +107,14 @@ def get_validation_errors(outfile, app=None):
for i, f in enumerate(opts.many_to_many): for i, f in enumerate(opts.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 objects # existing fields, m2m fields, m2m related objects or related objects
rel_opts = f.rel.to._meta
if f.rel.to not in models.get_models(): if f.rel.to not in models.get_models():
e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, f.rel.to))
# it is a string and we could not find the model it refers to
# so skip the next section
if isinstance(f.rel.to, (str, unicode)):
continue
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()
# If rel_name is none, there is no reverse accessor. # If rel_name is none, there is no reverse accessor.

View File

@ -152,7 +152,7 @@ class Options(object):
rel_objs = [] rel_objs = []
for klass in get_models(): for klass in get_models():
for f in klass._meta.fields: for f in klass._meta.fields:
if f.rel and self == f.rel.to._meta: if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta:
rel_objs.append(RelatedObject(f.rel.to, klass, f)) rel_objs.append(RelatedObject(f.rel.to, klass, f))
self._all_related_objects = rel_objs self._all_related_objects = rel_objs
return rel_objs return rel_objs
@ -186,7 +186,7 @@ class Options(object):
rel_objs = [] rel_objs = []
for klass in get_models(): for klass in get_models():
for f in klass._meta.many_to_many: for f in klass._meta.many_to_many:
if f.rel and self == f.rel.to._meta: if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta:
rel_objs.append(RelatedObject(f.rel.to, klass, f)) rel_objs.append(RelatedObject(f.rel.to, klass, f))
if app_cache_ready(): if app_cache_ready():
self._all_related_many_to_many_objects = rel_objs self._all_related_many_to_many_objects = rel_objs

View File

@ -108,6 +108,10 @@ class Car(models.Model):
colour = models.CharField(max_length=5) colour = models.CharField(max_length=5)
model = models.ForeignKey(Model) model = models.ForeignKey(Model)
class MissingRelations(models.Model):
rel1 = models.ForeignKey("Rel1")
rel2 = models.ManyToManyField("Rel2")
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.
@ -191,4 +195,6 @@ invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related
invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'. invalid_models.selfclashm2m: Accessor for m2m field 'm2m_4' clashes with related m2m field 'SelfClashM2M.selfclashm2m_set'. Add a related_name argument to the definition for 'm2m_4'.
invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_3'. invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_3'.
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.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: 'rel2' has m2m relation with model Rel2, which has not been installed
invalid_models.missingrelations: 'rel1' has relation with model Rel1, which has not been installed
""" """