以下内容之间似乎没有区别:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
打印出 Django 为这两种情况生成的 SQL 表明它是相同的。但是,我无法在任何地方找到这个官方文档,因此我担心在某些情况下可能只使用 modelb可能会导致不同于 modelb_id 的结果.
我特别感兴趣的是有人向我指出官方来源,确认这些东西是等价的。
请您参考如下方法:
TLDR:最好考虑框架作者的建议并使用模型字段名称。
Database Representation
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column. (You can change this explicitly by specifying db_column) However, your code should never have to deal with the database column name, unless you write custom SQL. You’ll always deal with the field names of your model object. Reference
模型字段子类 django.db.models.fields.Field . Field 类有一个 attname 字段,它是 documented internally in the source code作为解析要在模型对象上使用的属性的方法。
# 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)
作为执行流程的一部分 converting the QuerySet.filter names in the kwargs for the compiled SQL query ,名称被翻译成包含相应名称的模型字段的 PathInfo 元组。
On Line 1354 for django.db.models.sql.query.Query , 是以下行:
field = opts.get_field(name)
现在 opts 是 django.db.models.options.Options 的一个实例和 get_field方法委托(delegate)给 _forward_fields_map 或 fields_map 缓存属性。
当您查看这两个属性的实现时,您会看到它们返回一个字典映射 field.name 到 field 以及 field.attname 到 字段 。
这使得 modelb_id 或 modelb 从任一缓存属性解析为模型字段。
在我看来,将 modelb_id 或 modelb 作为关键字参数传递给 QuerySet.filter 并不重要。只是前一个关键字需要了解实现细节。
但是最好考虑框架作者的建议并使用模型字段名称。
