Django 查询 - id vs pk

Posted

技术标签:

【中文标题】Django 查询 - id vs pk【英文标题】:Django queries - id vs pk 【发布时间】:2010-01-29 23:10:53 【问题描述】:

在编写 django 查询时,可以同时使用 id/pk 作为查询参数。

Object.objects.get(id=1)
Object.objects.get(pk=1)

根据 django 的文档,我知道 pk 代表 Primary Key,它只是一个快捷方式。但是,不清楚何时应该使用 id 或 pk。

【问题讨论】:

这是各自的文档:for id 和 for pk What's the difference between Model.id and Model.pk in django?的可能重复 想知道是否有更多内容docs.djangoproject.com/en/1.11/topics/db/queries/… 在此处查看更新版本docs.djangoproject.com/en/2.2/topics/db/models/… 【参考方案1】:

没关系。 pk 更独立于实际的主键字段,即您无需关心主键字段是否称为 idobject_id 或其他。

如果您的模型具有不同的主键字段,它还可以提供更高的一致性。

【讨论】:

id 也是 Python 的内置函数,因此我更喜欢使用 pk。 是的,pk 更可取。请参阅 Python 标准库中的 documentation of built-in functionid。 (是same in Python 2。)【参考方案2】:

在我知道pk 总是返回id 的Django 项目中,当它不与id() 函数冲突时,我更喜欢使用id(除变量名外的所有地方)。原因是pk 是一个比id 慢7 倍的属性,因为在meta 中查找pk 属性名称需要时间。

%timeit obj.id
46 ns ± 0.187 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit obj.pk
347 ns ± 11.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

这里是相关的 Django 代码:

def _get_pk_val(self, meta=None):
    meta = meta or self._meta
    return getattr(self, meta.pk.attname)

def _set_pk_val(self, value):
    return setattr(self, self._meta.pk.attname, value)

pk = property(_get_pk_val, _set_pk_val)

当我需要使用名为pk 的变量时,这种情况确实很少见。我更喜欢使用更详细的内容,例如 user_id 而不是 pk

在整个项目中最好遵循相同的约定。在您的情况下,id 是参数名称,而不是属性,因此时间几乎没有区别。参数名称与内置 id() 函数的名称不冲突,所以在这里使用 id 是安全的。

总而言之,您可以选择使用字段名称id 还是pk 快捷方式。如果您不是为 Django 开发库并为所有模型使用automatic primary key fields,那么在任何地方都使用id 是安全的,这有时会更快。另一方面,如果您想要对(可能是自定义的)主键字段进行通用访问,请在任何地方使用pk。 1/3 微秒对网络来说不算什么。

【讨论】:

以上是关于Django 查询 - id vs pk的主要内容,如果未能解决你的问题,请参考以下文章

大 O 表示法:在 Django 模板中使用多个 forloops VS 在 vi​​ews.py 中使用过滤器的多个查询

django模型,如何动态设置查询的字段?

Django - 查询外键 ID 时避免连接?

在 Postgres DB 中使用大量 id 的 Django 查询过滤器

异步 Django 模型查询是不是可行?

Django 内连接查询集