From 0e692fda9ca57909216e68a998f2752885c23725 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Thu, 26 Jun 2008 10:50:25 +0000 Subject: [PATCH] Fixed the way symmetrical many-to-many relations are recorded in the Options class. These types of relations don't have reverse accessor names, so that name can be used by a normal field on the model. Fixed #7107. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7764 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/options.py | 11 +++++++---- tests/regressiontests/queries/models.py | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/django/db/models/options.py b/django/db/models/options.py index bc1aec62c1..c2313f221f 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -274,14 +274,17 @@ class Options(object): """ Initialises the field name -> field object mapping. """ - cache = dict([(f.name, (f, m, True, False)) for f, m in - self.get_fields_with_model()]) - for f, model in self.get_m2m_with_model(): - cache[f.name] = (f, model, True, True) + cache = {} + # We intentionally handle related m2m objects first so that symmetrical + # m2m accessor names can be overridden, if necessary. for f, model in self.get_all_related_m2m_objects_with_model(): cache[f.field.related_query_name()] = (f, model, False, True) for f, model in self.get_all_related_objects_with_model(): cache[f.field.related_query_name()] = (f, model, False, False) + for f, model in self.get_m2m_with_model(): + cache[f.name] = (f, model, True, True) + for f, model in self.get_fields_with_model(): + cache[f.name] = (f, model, True, False) if self.order_with_respect_to: cache['_order'] = OrderWrt(), None, True, False if app_cache_ready(): diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index a3e5561b86..cfbaf773d6 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -90,6 +90,15 @@ class Number(models.Model): def __unicode__(self): return unicode(self.num) +# Symmetrical m2m field with a normal field using the reverse accesor name +# ("valid"). +class Valid(models.Model): + valid = models.CharField(max_length=10) + parent = models.ManyToManyField('self') + + class Meta: + ordering = ['valid'] + # Some funky cross-linked models for testing a couple of infinite recursion # cases. class X(models.Model): @@ -768,5 +777,9 @@ just count the number of results). >>> len(Tag.objects.order_by('parent__name')) 5 +Bug #7107 -- this shouldn't create an infinite loop. +>>> Valid.objects.all() +[] + """}