Say I have a ForeignKey field called "parent" with a related_name of "children":
class Item(PolymorphicModel):
title = models.CharField()
parent = models.ForeignKey(
"self", related_name='children', null=True, blank=True, on_delete=models.CASCADE)
class Parent(Item):
pass
class Child(Item):
pass
Why is it that I can only add the child to the parent but I get an error if I try to add a parent to the child?
So this works:
p1 = Parent.objects.create(title="Parent 1")
c1 = Child.objects.create(title="Child 1")
print(p1.children)
#<PolymorphicQuerySet []>
p1.children.add(c1)
But this doesn't:
p1 = Parent.objects.create(title="Parent 1")
c1 = Child.objects.create(title="Child 1")
print(c1.parent)
# None
c1.parent.add(p1)
# AttributeError: 'NoneType' object has no attribute 'add'
Do I just have to add to the Parent's children field each time? Is there no way to add to the Child's parent instead? Is there any reason why adding to the Child's parent doesn't work or shouldn't be used?
I'm also a little confused about when/how to use "_set" in this circumstance (if that's relevant). So following the format of Django's Many-to-one example, the following doesn't work for me either:
p1 = Parent.objects.create(title="Parent 1")
c1 = Child.objects.create(title="Child 1")
p1.children.add(c1)
print(p1.children_set.all())
# AttributeError: 'p1' object has no attribute 'children_set'
print(c1.parent_set.all())
# AttributeError: 'c1' object has no attribute 'parent_set'
print(p1.item_set.all())
# AttributeError: 'p1' object has no attribute 'item_set'
So I think that you are confusing yourself here with
parentandchildnaming here. Therelated_namefield inForeignKeyessentially tells the model to set up a relationship to quickly find all related instances of the model with the givenForeignKey. When you callp1.children, you are getting the correct output because there are no related instances top1. You similarly get the correct output when you callc1.parentand getNone. The line that I copied and pasted below is what causes this. By settingnull=True, you are saying to instantiate theIteminstance (whether it'sParentorChild), with a nullparentfield (in python, null isNone).Your perceived problem comes when you call
c1.parent.add(). Since you have not setparentto anything, its value isNone, and it likewise does not have anadd()method. What you should be doing is settingparent=[some instance of Parent]. Then, when you want to get thechildrenof a givenParentinstance, let's sayp1, you can callp1.children, and you will get a queryset full ofChildinstances whoseparentfield has been set to the foreign key of thatParentinstance.