#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 , 18 years ago
comment:2 by , 18 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.