python - 在 Django 的 ORM 中只使用 `foreign_key=` 和 `foreign_key_id=` 有什么区别吗?
问题描述
以下之间似乎没有区别:
ModelA.objects.filter(modelb_id=a_model_id)
ModelA.objects.filter(modelb=a_model_id)
打印出 Django 为这两种情况生成的 SQL 表明它是相同的。但是,我无法在任何地方找到此正式文档,因此我担心在某些情况下使用 justmodelb
可能会导致与modelb_id
.
我特别感兴趣的是有人将我指向确认这些东西是等效的官方消息来源。
解决方案
TLDR:最好考虑框架作者的建议并使用模型字段名称。
数据库表示
在幕后,Django 将“_id”附加到字段名称以创建其数据库列名称。在上面的示例中,汽车模型的数据库表将有一个manufacturer_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)
作为为编译的 SQL 查询转换 kwargs 中的QuerySet.filter
名称的执行流程的一部分,名称被转换为PathInfo
包含相应名称的模型字段的元组。
在第 1354django.db.models.sql.query.Query
行,是以下行:
field = opts.get_field(name)
Nowopts
是一个实例,django.db.models.options.Options
方法get_field
委托给_forward_fields_map
或fields_map
缓存的属性。
当您查看这两个属性的实现时,您会看到它们返回一个字典映射field.name
tofield
和field.attname
to field
。
这使得它modelb_id
可以modelb
从任一缓存属性解析为模型字段。
在我看来,这并不重要,modelb_id
或者modelb
作为关键字参数传递给QuerySet.filter
. 只有前一个关键字需要了解实现细节。
但是,最好考虑框架作者的建议并使用模型字段名称。
推荐阅读
- python - 即使在 Django Rest Framework 中配置了所有内容,我也收到“请求的资源上不存在 Access-Control-Allow-Origin 标头”
- python - Python 单元测试开始目录不可导入
- sql - 公用表表达式语法错误
- arrays - 用不同的数组值替换 JSON 中的符号
- html - Highcharts Network Graph Arrow Links
- azure - 在 Azure 规模集 vm 之间同步文件
- python - 是否可以通过 C++ 扩展强制多个 python 进程共享相同的内存?
- javascript - HttpClient Angular 9将嵌套的json转换为嵌套对象
- python - 在 conda env 中使用 pandas.read_html() 函数时出现错误“找不到 html5lib”
- asp.net-core-3.1 - ASP.Net Core 3.1 Razor 页面针对 Active Directory 进行身份验证