I have this strange problem with one of my Django models and I was able to fix it but don't understand what is happening.
These are the models:
class Player(models.Model):
facebook_name = models.CharField(max_length=100)
nickname = models.CharField(max_length=40, blank=True)
def __unicode__(self):
return self.nickname if self.nickname else self.facebook_name
class Team(models.Model):
name = models.CharField(max_length=50, blank=True)
players = models.ManyToManyField(Player)
def __unicode__(self):
name = '(' + self.name + ') ' if self.name else ''
return name + ", ".join([unicode(player) for player in self.players.all()])
Whenever I make a new (empty) Team
object and want to get players
from it, I got a RuntimeError: maximum recursion depth exceeded
.
For example:
>>> team = Team()
>>> team.players
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 897, in __get__
through=self.field.rel.through,
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 586, in __init__
(instance, source_field_name))
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/base.py", line 421, in __repr__
u = six.text_type(self)
File "/Users/walkman/Projects/fociadmin/fociadmin/models.py", line 69, in __unicode__
return name + ", ".join([unicode(player) for player in self.players.all()])
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 897, in __get__
through=self.field.rel.through,
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 586, in __init__
(instance, source_field_name))
File "/Users/walkman/Projects/fociadmin/venv/lib/python2.7/site-packages/django/db/models/base.py", line 421, in __repr__
u = six.text_type(self)
File "/Users/walkman/Projects/fociadmin/fociadmin/models.py", line 69, in __unicode__
return name + ", ".join([unicode(player) for player in self.players.all()])
...
Why is this happening? I was able to fix it by checking for pk
and only generate the name then, but what I think it should work the way is returning only the name because ", ".join...
would be an empty list. Instead, some recursion occurs which I don't understand.
The “maximum recursion depth exceeded in comparison” error is raised when you try to execute a function that exceeds Python's built in recursion limit. You can fix this error by rewriting your program to use an iterative approach or by increasing the recursion limit in Python.
Conclusion. The recursion depth limit in Python is by default 1000 . You can change it using sys. setrecursionlimit() function.
As the name suggests, Recursionerror may occur when we are dealing with recursive functions. When we run the recursion function for a large number of times, recursion error is thrown. Python has a limit on the number of times a recursive function can call itself.
Try increasing the recursion limit ( sys. setrecursionlimit ) or re-writing your code without recursion. Return the current value of the recursion limit, the maximum depth of the Python interpreter stack. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python.
The problem is that you can't access the team.players
field when the Team
instance is not yet saved to the database. Trying to do this will raise a ValueError
.
However, while trying to raise this ValueError
, the code will try to get a representation of your team
object which will indirectly call unicode(team)
. This will try to access self.players
, which will try to raise another ValueError
before the first one is raised. This goes on until the maximum recursion depth is reached, but there is still no ValueError
thrown. Therefore, you'll only see the RuntimeError
.
The same would (should?) happen if you did either of the following:
>>> team
>>> repr(team)
>>> unicode(team)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With