Django查询 - id vs pk

267

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

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

我知道pk代表主键(primary key),根据 Django 的文档,它只是一个快捷方式。然而,什么情况下应该使用 id 或 pk 不太清楚。


以下是相关文档:idpk - Lutz Prechelt
1
可能是django中Model.id和Model.pk有什么区别?的重复问题。 - Travis
想知道是否还有更多内容,请参阅 https://docs.djangoproject.com/en/1.11/topics/db/queries/#copying-model-instances - Rajan Chauhan
请在此处检查更新版本:https://docs.djangoproject.com/en/2.2/topics/db/models/#automatic-primary-key-fields - Trect
2个回答

280

没关系。 pk 与实际的主键字段更加独立,即您不需要关心主键字段是称为 id 还是 object_id 或其他内容。

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


63
“id”在Python中是一个内置函数,因此我更倾向于使用“pk”。 - Thierry Lam
10
是的,pk更可取。请参阅Python标准库中内置函数id的文档(Python 2中也是一样的)。 - Lutz Prechelt
我猜他们更多地谈论ORM的id,而不是Python的id函数。 - Devang Hingu
使用pk,因为过一段时间后,您将拥有具有自定义主键的项目,而这些主键的名称不是ID,因此可能会引起问题。习惯于使用pk,因为它始终指代主键字段,无论其名称如何。 - BGOPC
使用pk,因为过一段时间后,您将拥有具有自定义主键的项目,而这些主键的名称不是ID,因此可能会引起问题。习惯使用pk,因为它始终指代主键字段,无论其名称是什么。 - undefined

68
在Django项目中,当我知道pk总是返回id时,除变量名以外的其他地方,我更喜欢使用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开发库并且对所有模型使用自动主键字段,那么在任何地方使用id都是安全的,有时速度更快。

另一方面,如果你想普遍访问(可能是定制的)主键字段,则应在每个地方使用pk
对于Web来说,三分之一微秒根本不算什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接