Почему model._meta.get_fields() возвращает неожиданные имена столбцов отношений, и можно ли это предотвратить?
Представьте, что у меня есть несколько моделей, как показано ниже:
class User(AbstractUser):
pass
class Medium(models.Model):
researcher = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name="medium_researcher")
old_medium_name = models.CharField(max_length=20, null=True, blank=True)
class Uptake(models.Model):
material_quality = models.CharField(max_length=20, null=True, blank=True)
medium = models.ForeignKey(Medium, on_delete=models.CASCADE, blank=True, null=True, related_name="uptake_medium")
Теперь у меня есть функция, возвращающая имена всех столбцов для создания некоторого обзора в моем HTML в таком виде:
from database.models import Medium
MODEL_HEADERS=[f.name for f in Medium._meta.get_fields()]
MODEL_HEADERS
['uptake_medium', 'id', 'researcher', 'old_medium_name']
Почему это возвращает uptake_medium
? Поскольку это отношение ForeignKey, установленное в модели Uptake
, оно должно присутствовать только в модели Uptake
, верно? Когда я просматриваю модели администратора, этот столбец не отображается, ни в модели db.sqlite3 при проверке Uptake
, поэтому он кажется как бы скрытым, и отображается только при запросе _meta
. Отношения кажутся правильными... Это вызывает много проблем в моем коде, и было бы здорово, если бы можно было возвращать только "не мета" столбцы. Как мне следует поступить?
Почему это возвращает uptake_medium? Поскольку это отношение
ForeignKey
, установленное в моделиUptake
, оно должно присутствовать только в моделиUptake
, верно?Вы можете получить доступ к отношению в обратном порядке, например:
my_medium.uptake_medium.all()
для получения всех
Update
, связанных с экземпляромMedium
с именемmedium
.Вы также можете фильтровать по этому полю, например:
Medium.objects.filter(uptake_medium__material_quantity=42)
поэтому оно доступно так же, как и любое другое поле.
Вы можете фильтровать с помощью:
from django.db.models.fields.reverse_related import ManyToOneRel [f.name for f in Medium._meta.get_fields() if not isinstance(f, ManyToOneRel)]