Подтвердить что ты не робот

Django Foreign Key: получить связанную модель?

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

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

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)

и я хочу:

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

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

4b9b3361

Ответ 1

Если ModelA имеет поле FK с именем "foo", то вы можете получить связанную модель:

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

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

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

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

Ответ 2

При попытке извлечь такие отношения, я использую много экспериментов с командной строкой. Обычный шаблон, который я использую, - _=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. Один и тот же базовый шаблон может использоваться для изучения обратных отношений, отношений "многие ко многим", начиная с экземпляра, а не класса и т.д.