mirror of
https://github.com/django/django.git
synced 2025-10-25 14:46:09 +00:00
Fixes #2653 -- Modified related field utility methods to return None as the related name for symmetrical m2m fields on self. Updated validators and unit tests to account for the new behavior.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3734 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -903,27 +903,32 @@ def get_validation_errors(outfile, app=None):
|
||||
|
||||
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
|
||||
rel_query_name = f.related_query_name()
|
||||
for r in rel_opts.fields:
|
||||
if r.name == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
if r.name == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
for r in rel_opts.many_to_many:
|
||||
if r.name == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
if r.name == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
for r in rel_opts.get_all_related_many_to_many_objects():
|
||||
if r.field is not f:
|
||||
# If rel_name is none, there is no reverse accessor.
|
||||
# (This only occurs for symmetrical m2m relations to self).
|
||||
# If this is the case, there are no clashes to check for this field, as
|
||||
# there are no reverse descriptors for this field.
|
||||
if rel_name is not None:
|
||||
for r in rel_opts.fields:
|
||||
if r.name == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
if r.name == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
for r in rel_opts.many_to_many:
|
||||
if r.name == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
if r.name == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name))
|
||||
for r in rel_opts.get_all_related_many_to_many_objects():
|
||||
if r.field is not f:
|
||||
if r.get_accessor_name() == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with related m2m 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))
|
||||
if r.get_accessor_name() == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with related m2m 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))
|
||||
for r in rel_opts.get_all_related_objects():
|
||||
if r.get_accessor_name() == rel_name:
|
||||
e.add(opts, "Accessor for m2m field '%s' clashes with related m2m 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, "Accessor for m2m 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))
|
||||
if r.get_accessor_name() == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m field '%s' clashes with related m2m 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))
|
||||
for r in rel_opts.get_all_related_objects():
|
||||
if r.get_accessor_name() == rel_name:
|
||||
e.add(opts, "Accessor for m2m 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))
|
||||
if r.get_accessor_name() == rel_query_name:
|
||||
e.add(opts, "Reverse query name for m2m 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 m2m 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))
|
||||
|
||||
# Check admin attribute.
|
||||
if opts.admin is not None:
|
||||
|
||||
@@ -131,6 +131,9 @@ class RelatedObject(object):
|
||||
# many-to-many objects. It uses the lower-cased object_name + "_set",
|
||||
# but this can be overridden with the "related_name" option.
|
||||
if self.field.rel.multiple:
|
||||
# If this is a symmetrical m2m relation on self, there is no reverse accessor.
|
||||
if getattr(self.field.rel, 'symmetrical', False) and self.model == self.parent_model:
|
||||
return None
|
||||
return self.field.rel.related_name or (self.opts.object_name.lower() + '_set')
|
||||
else:
|
||||
return self.field.rel.related_name or (self.opts.object_name.lower())
|
||||
|
||||
Reference in New Issue
Block a user