#python #django #django-models
#python #django #django-модели
Вопрос:
Я пытался получить доступ к дочернему объекту через родительский объект, поскольку я хочу выполнять разные операции в зависимости от типа объекта. Что у меня есть, так это:
#models.py
class A(models.Model):
...
class B(A):
field1 = models.CharField(...)
...
class C(A):
field2 = models.IntegerField(...)
Я мог бы выполнить 2 цикла for и выполнить то, что я хочу:
for obj in B.objects.all():
if field1 == 'something':
do some operation
for obj in C.objects.all():
if field2 == 5:
do some other operation
Но я подумал, разве невозможно сделать это с помощью цикла 1 for и получить доступ к дочернему объекту через родительский?
for obj in A.objects.all():
if obj.b and obj.b.field1 == 'something':
do some operation
elif obj.c and obj.c.field2 == 5:
do some other operation
Я также подумал, что select_related может помочь, но там сказано, что это работает только для ForeignKey
.
Более того, я надеялся сделать это без использования дополнительных приложений, таких как django-model-utils или django-polymorphic, потому что я чувствую, что для этого должна быть простая операция запроса.
Комментарии:
1. Я немного запутался в вашем запросе, но у меня аналогичный вопрос. если obj.b и obj.b.field1 == ‘something’: у obj нет атрибута «b», у obj.c и obj.c.field2 obj также нет атрибута «c»
Ответ №1:
Вы можете перейти к дочернему объекту из родительского, как вы делали в последнем цикле for, но вам также нужно будет проверить, существует ли дочерний объект для родительского, например:
for obj in A.objects.all():
try:
if obj.b.field1 == 'something':
do some operation
except ObjectDoesNotExist:
# obj does not have a child of class B
try:
if obj.c.field2 == 5:
do some other operation
except ObjectDoesNotExist:
# obj does not have a child of class C
Вы также можете объединить это в один запрос, используя Q objects:
A.objects.filter(Q(b__isnull=False, b__field1='something') | Q(c__isnull=False, c__field2=5))
Это вернет объекты класса A
Ответ №2:
Возможно, это может быть кому-то полезно. hasattr
в противном случае True
будет возвращен False
для правильного дочернего экземпляра. Пожалуйста, обратите внимание, что имя класса указано в smallcase для hasattr
параметра.
for obj in A.objects.all():
if obj.hasattr('b'):
# do something specific to b
if obj.hasattr('c'):
# do something specific to c