#django #django-models #django-polymorphic
#django #django-модели #django-полиморфный
Вопрос:
Допустим, у меня есть поле внешнего ключа с именем «parent» с именем related_name «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
Почему я могу добавить дочерний элемент только к родительскому элементу, но я получаю сообщение об ошибке, если пытаюсь добавить родительский элемент к дочернему элементу?
Итак, это работает:
p1 = Parent.objects.create(title="Parent 1")
c1 = Child.objects.create(title="Child 1")
print(p1.children)
#<PolymorphicQuerySet []>
p1.children.add(c1)
Но это не:
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'
Должен ли я просто каждый раз добавлять в дочернее поле родительского элемента? Нет ли способа добавить к родительскому элементу дочернего элемента вместо этого? Есть ли какая-либо причина, по которой добавление к родительскому элементу дочернего элемента не работает или не должно использоваться?
Я также немного смущен тем, когда / как использовать «_set» в этом случае (если это уместно). Итак, следуя формату примера Django «Многие к одному«, следующее для меня тоже не работает:
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'
Ответ №1:
Поэтому я думаю, что вы путаете себя здесь с parent
и child
называете здесь. related_name
Поле в ForeignKey
основном указывает модели установить связь , чтобы быстро найти все связанные экземпляры модели с заданным ForeignKey
. Когда вы вызываете p1.children
, вы получаете правильный вывод, потому что нет связанных экземпляров p1
. Вы точно так же получаете правильный вывод, когда вызываете c1.parent
и получаете None
. Строка, которую я скопировал и вставил ниже, является причиной этого. Устанавливая null=True
, вы говорите о создании экземпляра Item
экземпляра (будь то Parent
or Child
) с нулевым parent
полем (в python значение null равно None
).
Ваша предполагаемая проблема возникает при вызове c1.parent.add()
. Поскольку вы ничего не установили parent
, его значение равно None
, и у него также нет add()
метода. Что вы должны делать, так это устанавливать parent=[some instance of Parent]
. Затем, когда вы хотите получить children
Parent
, скажем, данный экземпляр p1
, вы можете вызвать p1.children
, и вы получите набор запросов, полный Child
экземпляров, parent
в поле которых был установлен внешний ключ этого Parent
экземпляра.
parent = models.ForeignKey(
"self", related_name='children', null=True, blank=True, on_delete=models.CASCADE)