1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

magic-removal: Moved related name clash check logic out of Options, and into the

validation phase of model loading.


git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2155 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2006-01-29 01:38:48 +00:00
parent d580b42d45
commit 5bac096399
3 changed files with 34 additions and 38 deletions

View File

@ -1,7 +1,7 @@
# Django management-related functions, including "CREATE TABLE" generation and # Django management-related functions, including "CREATE TABLE" generation and
# development-server initialization. # development-server initialization.
import django import django
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
import os, re, sys, textwrap import os, re, sys, textwrap
from optparse import OptionParser from optparse import OptionParser
@ -766,6 +766,8 @@ class ModelErrorCollection:
def get_validation_errors(outfile): def get_validation_errors(outfile):
"Validates all installed models. Writes errors, if any, to outfile. Returns number of errors." "Validates all installed models. Writes errors, if any, to outfile. Returns number of errors."
from django.db import models from django.db import models
from django.db.models.fields.related import RelatedObject
e = ModelErrorCollection(outfile) e = ModelErrorCollection(outfile)
for cls in models.get_models(): for cls in models.get_models():
opts = cls._meta opts = cls._meta
@ -802,6 +804,20 @@ def get_validation_errors(outfile):
if f.db_index not in (None, True, False): if f.db_index not in (None, True, False):
e.add(opts, '"%s" field: "db_index" should be either None, True or False.' % f.name) e.add(opts, '"%s" field: "db_index" should be either None, True or False.' % f.name)
# Check to see if the related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
if f.rel:
rel_opts = f.rel.to._meta
rel_name = RelatedObject(f.rel.to, cls, f).OLD_get_accessor_name()
if rel_name in [r.name for r in rel_opts.fields]:
e.add(opts, "'%s.%s' related field: Clashes with field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.name for r in rel_opts.many_to_many]:
e.add(opts, "'%s.%s' related field: Clashes with m2m field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_many_to_many_objects()]:
e.add(opts, "'%s.%s' related field: Clashes with related m2m field '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_objects() if r.field is not f]:
e.add(opts, "'%s.%s' related field: Clashes with related field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
# Check for multiple ManyToManyFields to the same object, and # Check for multiple ManyToManyFields to the same object, and
# verify "singular" is set in that case. # verify "singular" is set in that case.
for i, f in enumerate(opts.many_to_many): for i, f in enumerate(opts.many_to_many):
@ -809,6 +825,20 @@ def get_validation_errors(outfile):
if f.rel.to._meta == previous_f.rel.to._meta and f.rel.singular == previous_f.rel.singular: if f.rel.to._meta == previous_f.rel.to._meta and f.rel.singular == previous_f.rel.singular:
e.add(opts, 'The "%s" field requires a "singular" parameter, because the %s model has more than one ManyToManyField to the same model (%s).' % (f.name, opts.object_name, previous_f.rel.to._meta.object_name)) e.add(opts, 'The "%s" field requires a "singular" parameter, because the %s model has more than one ManyToManyField to the same model (%s).' % (f.name, opts.object_name, previous_f.rel.to._meta.object_name))
# Check to see if the related m2m field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
if f.rel:
rel_opts = f.rel.to._meta
rel_name = RelatedObject(f.rel.to, cls, f).OLD_get_accessor_name()
if rel_name in [r.name for r in rel_opts.fields]:
e.add(opts, "'%s.%s' related m2m field: Clashes with field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.name for r in rel_opts.many_to_many]:
e.add(opts, "'%s.%s' related m2m field: Clashes with m2m field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_many_to_many_objects() if r.field is not f]:
e.add(opts, "'%s.%s' related m2m field: Clashes with related m2m field '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
elif rel_name in [r.OLD_get_accessor_name() for r in rel_opts.get_all_related_objects()]:
e.add(opts, "'%s.%s' related m2m field: Clashes with related field on '%s.%s'" % (opts.object_name, f.name, rel_opts.object_name, rel_name))
# Check admin attribute. # Check admin attribute.
if opts.admin is not None: if opts.admin is not None:
if not isinstance(opts.admin, models.AdminOptions): if not isinstance(opts.admin, models.AdminOptions):

View File

@ -27,8 +27,6 @@ get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
class FieldDoesNotExist(Exception): class FieldDoesNotExist(Exception):
pass pass
class FieldCollision(Exception):
pass
def manipulator_validator_unique(f, opts, self, field_data, all_data): def manipulator_validator_unique(f, opts, self, field_data, all_data):
"Validates that the value is unique for this field." "Validates that the value is unique for this field."

View File

@ -1,6 +1,6 @@
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject
from django.db.models.fields.related import ManyToMany from django.db.models.fields.related import ManyToMany
from django.db.models.fields import AutoField, FieldDoesNotExist, FieldCollision from django.db.models.fields import AutoField, FieldDoesNotExist
from django.db.models.loading import get_models from django.db.models.loading import get_models
from django.db.models.query import orderlist2sql from django.db.models.query import orderlist2sql
from bisect import bisect from bisect import bisect
@ -123,23 +123,7 @@ class Options:
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 self == f.rel.to._meta:
rel_obj = RelatedObject(f.rel.to, klass, f) rel_objs.append(RelatedObject(f.rel.to, klass, f))
# Check to see if the new related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
if rel_obj.OLD_get_accessor_name() in [r.name for r in f.rel.to._meta.fields]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.name for r in f.rel.to._meta.many_to_many]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing m2m field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.name for r in f.rel.to._meta.get_all_related_many_to_many_objects()]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing related m2m field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.OLD_get_accessor_name() for r in rel_objs]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing related field on ' + self.object_name
else:
rel_objs.append(rel_obj)
self._all_related_objects = rel_objs self._all_related_objects = rel_objs
return rel_objs return rel_objs
@ -173,23 +157,7 @@ class Options:
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 self == f.rel.to._meta:
rel_obj = RelatedObject(f.rel.to, klass, f) rel_objs.append(RelatedObject(f.rel.to, klass, f))
# Check to see if the new related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
if rel_obj.OLD_get_accessor_name() in [r.name for r in f.rel.to._meta.fields]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.name for r in f.rel.to._meta.many_to_many]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing m2m field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.OLD_get_accessor_name() for r in f.rel.to._meta.get_all_related_objects()]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing related field on ' + self.object_name
elif rel_obj.OLD_get_accessor_name() in [r.name for r in rel_objs]:
raise FieldCollision, 'Related field ' + klass._meta.object_name + \
'.' + f.name + ' clashes with existing related m2m field on ' + self.object_name
else:
rel_objs.append(rel_obj)
self._all_related_many_to_many_objects = rel_objs self._all_related_many_to_many_objects = rel_objs
return rel_objs return rel_objs