TLDR: Лучше учесть рекомендации авторов каркаса и использовать имена полей модели.
Представление базы данных
За кулисами Django добавляет «_id» к имени поля, чтобы создать его имя столбца базы данных. В приведенном выше примере таблица базы данных для модели автомобиля будет иметь столбец factory_id. (Вы можете изменить это явно, указав db_column). Однако ваш код никогда не должен иметь дело с именем столбца базы данных, если вы не пишете пользовательский SQL. Вы всегда будете иметь дело с именами полей вашего модельного объекта. Ссылка
Подкласс моделей полей django.db.models.fields.Field
. Класс Field
имеет поле attname
, которое задокументировано внутри исходного кода как способ разрешения атрибута для использования в объекте модели.
# A guide to Field parameters:
#
# * name: The name of the field specified in the model.
# * attname: The attribute to use on the model object. This is the same as
# "name", except in the case of ForeignKeys, where "_id" is
# appended.
# * db_column: The db_column specified in the model (or None).
# * column: The database column for this field. This is the same as
# "attname", except if db_column is specified.
#
# Code that introspects values, or does other dynamic things, should use
# attname. For example, this gets the primary key value of object "obj":
#
# getattr(obj, opts.pk.attname)
Как часть потока выполнения к преобразованию имен QuerySet.filter
в kwargs для скомпилированного запроса SQL , имена преобразуются в кортежи PathInfo
, содержащие поля модели для соответствующих имен.
В строке 1354 для django.db.models.sql.query.Query
есть следующая строка:
field = opts.get_field(name)
Теперь opts
является экземпляром django.db.models.options.Options
, а метод get_field
делегирует кешированные свойства _forward_fields_map
или fields_map
.
Когда вы посмотрите на реализацию этих двух свойств, вы увидите, что они возвращают словарь, отображающий field.name
в field
вместе с field.attname
в field
.
Таким образом, modelb_id
или modelb
разрешается в поле модели из любого из кэшированных свойств.
На мой взгляд, не имеет значения, что modelb_id
или modelb
передается в качестве ключевого аргумента QuerySet.filter
. Только для того, чтобы первое ключевое слово требовало знания деталей реализации.
Однако лучше учесть рекомендации авторов каркаса и использовать имена полей модели.