Simply put I have two models
A dialogue model:
class Dialogue(models.Model):
content = models.TextField()
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
And a choice model:
class Choice(models.Model):
option = models.CharField(max_length = 255)
content = models.TextField()
dialogue = models.ForeignKey(
Dialogue,
related_name = "choices",
blank = True,
null = True,
on_delete = models.CASCADE
)
subChoices = models.ForeignKey(
"self",
related_name = "parent",
blank = True,
null = True,
on_delete = models.CASCADE
)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
You may have noticed the recursive ForeignKey "Choice.subChoices". This is where my issue lies.
If I attempt to use the add() method via the instance of this model that I want to be added to a Choice's list of further choices, I get a "'Choice' object has no attribute 'add'". If I attempt to the the reverse and add an instance of the Choice model to a Choice's parents attribute it overwrites instead of creating a query set.
Examples of both below:
choice1 = Choice.objects.get(id = 1)
choice2 = Choice.objects.get(id = 2)
choice3 = Choice.objects.get(id = 3)
choice1.subChoices.add(choice2)
>>> AttributeError: 'Choice' object has no attribute 'add'
choice2.parent.add(choice1)
choice3.parent.add(choice2)
print(choice1.subChoices)
>>> Choice object(3)
A print statement of choice1.subChoices.all() returns a similar attribute error.
My goal here is to have Choice objects optionally have a list of Choice objects, should the outcome of a choice result in a further selection.
You defined this in the wrong way. The ForeignKey
acts as a many-to-one relation, not a one-to-many relation. The ForeignKey
thus always points to a parent, not to its children.
This ForeignKey
should thus be named parent
and the related_name
should be named subChoices
. The modeling thus should look like:
class Choice(models.Model):
option = models.CharField(max_length = 255)
content = models.TextField()
dialogue = models.ForeignKey(
Dialogue,
related_name='choices',
blank=True,
null=True,
on_delete=models.CASCADE
)
parent = models.ForeignKey(
'self',
related_name='subChoices',
blank=True,
null=True,
on_delete = models.CASCADE
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)