#7107 closed (fixed)
ManyToMany self-referential models *need* a related_name
Reported by: | tsouanas | Owned by: | Malcolm Tredinnick |
---|---|---|---|
Component: | Uncategorized | Version: | dev |
Severity: | Keywords: | qsrf-cleanup manytomany, infinite loop | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Without a related_name, self-referential ManyToMany models seem cause an infinite loop when trying to insert new objects.
Change History (9)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
Using this model, when I try to edit it from the admin interface (newforms-admin) without the related_name attribute, I get a
Infinite loop caused by ordering.
error.
(I also used to have an "order_with_respect_to = 'parents'" inside the Meta class but I removed it.)
class Topic(models.Model): topic = models.CharField(max_length=128) parents = models.ManyToManyField('self', related_name='topic_parents', null=True, blank=True) class Meta: ordering = ('topic',) def ancestors(self): if not self.parents: return [self] else: return sum([parent.ancestors() for parent in self.parents], [self]) def subtopic_of(self, topic): return topic in self.ancestors() def related_with(self, topic): return self.subtopic_of(topic) or topic.subtopic_of(self)
comment:3 by , 17 years ago
Keywords: | qsrf-cleanup added |
---|
comment:4 by , 17 years ago
milestone: | → 1.0 |
---|
comment:5 by , 17 years ago
Component: | Documentation → Uncategorized |
---|---|
Version: | SVN → newforms-admin |
I'm going to reassign this to the newforms-admin branch, since it doesn't seem to be core-related. The normal core code will not be using parent
anywhere in the ordering querying, since it's just not specified. If newforms-admin is somehow introducing an implicit ordering on that many-to-many relation, it needs to work out how it's going to avoid the infinite loop problem. I haven't looked at the newforms-admin code to see what's going on here, but, as indicated in the first comment, I can't repeat it with normal code on trunk.
So Brian or Karen ... any big ideas what's going on here?
comment:6 by , 17 years ago
Version: | newforms-admin → SVN |
---|
I don't think the problem is in the admin. I can recreate the problem by just doing a Topic.objects.all() in a python shell with the given model. The problem seems to relate to having specified an ordering on a field that is identical except for case to the name of the Model. If I change the model name so that is different than the field name then the problem goes away. That is, given these models:
class Topic(models.Model): topic = models.CharField(max_length=128) parents = models.ManyToManyField('self', null=True, blank=True) class Meta: ordering = ('topic',) class TopicModel(models.Model): topic = models.CharField(max_length=128) parents = models.ManyToManyField('self', null=True, blank=True) class Meta: ordering = ('topic',)
this is what I see:
Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12) [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> import django >>> django.get_version() u'0.97-pre-SVN-7739' >>> from m2m.models import Topic,TopicModel >>> Topic.objects.all() Traceback (most recent call last): File "<console>", line 1, in <module> File "/homedir/django/trunk/django/db/models/query.py", line 129, in __repr__ return repr(list(self)) File "/homedir/django/trunk/django/db/models/query.py", line 141, in __len__ self._result_cache.extend(list(self._iter)) File "/homedir/django/trunk/django/db/models/query.py", line 248, in iterator for row in self.query.results_iter(): File "/homedir/django/trunk/django/db/models/sql/query.py", line 200, in results_iter for rows in self.execute_sql(MULTI): File "/homedir/django/trunk/django/db/models/sql/query.py", line 1464, in execute_sql sql, params = self.as_sql() File "/homedir/django/trunk/django/db/models/sql/query.py", line 247, in as_sql ordering = self.get_ordering() File "/homedir/django/trunk/django/db/models/sql/query.py", line 583, in get_ordering self.model._meta, default_order=asc): File "/homedir/django/trunk/django/db/models/sql/query.py", line 627, in find_ordering_name order, already_seen)) File "/homedir/django/trunk/django/db/models/sql/query.py", line 621, in find_ordering_name raise FieldError('Infinite loop caused by ordering.') FieldError: Infinite loop caused by ordering. >>> TopicModel.objects.all() [] >>>
comment:7 by , 17 years ago
Owner: | changed from | to
---|---|
Triage Stage: | Unreviewed → Accepted |
Right, my bad then. I'll fix it.
comment:8 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I cannot repeat this problem. Can you please provide a short example model and instructions for how to trigger the problem?
I've been using this model for testing and I can insert, query and remove things from the m2m field without any problems.