Вопрос по python, foreign-keys, django, django-models – Django Foreign Key: получить связанную модель?

15

Можно ли получить связанную модель внешнего ключа через само поле внешнего ключа?

Например, если у меня есть 3 модели:

<code>class ModelA(models.Model)
    field1 = models.CharField(max_length=10)

class ModelB(models.Model)
    field1 = models.CharField(max_length=10)

class ModelC(models.Model)
    field1 = models.CharField(max_length=10)
    field2 = models.ForeignKey(ModelA)
    field3 = models.ForeignKey(ModelB)
</code>

и я хочу сделать:

<code>for field in ModelC._meta.fields:
    if field.get_internal_type() == "ForeignKey":
        #get the related model for field e.g. ModelA or ModelB
</code>

Возможно ли это, используя только сами модели, а не экземпляры моделей?

Ваш Ответ

2   ответа
24

foo & quot ;, то вы можете получить соответствующую модель:

ModelA._meta.get_field('foo').rel.to

С вашим кодом это будет выглядеть так:

for field in ModelC._meta.fields:
    if field.get_internal_type() == "ForeignKey":
        print field.rel.to

Если это выяснилось с помощью дополнения табуляции в оболочке давно, оно все еще работает. Возможно, вы захотите научиться использовать оболочку для обратного инжиниринга подобных вещей.

Обновление: в недавно выпущенном Django 2.0 это выглядит как & quot; rel & quot; больше не поле ForeignKey. Вы можете попробовать:ModelA._meta.get_field('foo').related_model, Я выясняю это, набирая & quot; tab & quot; для автозаполнения в командной строке.
1

Когда я пытаюсь извлечь такие отношения, я использую много экспериментов в командной строке. Общий шаблон, который я использую,_=starting_point.<chained_attributes>;pprint((_, dir(_))), Например:

_=ModelC;pprint((_, dir(_)))
_=ModelC.field2;pprint((_, dir(_)))
_=ModelC.field2.field;pprint((_, dir(_)))
_=ModelC.field2.field.rel;pprint((_, dir(_)))
_=ModelC.field2.field.rel.to;pprint((_, dir(_)))

(Вам нужно сделатьfrom pprint import pprint во-первых, естественно.) Это позволяет мне экспериментировать с добавлением / удалением атрибутов до тех пор, пока я не найду нужный элемент ... и при этом буду четко видеть, что я получил и что доступно на следующем уровне ниже. От этого я получаю ModelC.field2.field.rel.to == ModelA, Один и тот же базовый шаблон можно использовать для изучения обратных отношений, отношений «многие ко многим», начиная с экземпляра, а не с класса и т. Д.

Похожие вопросы