Django查询 - id vs pk

时间:2010-01-29 23:10:54

标签: django orm primary-key

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

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

根据django的文档,我知道pk代表主键,只是一个捷径。但是,不清楚何时应该使用id或pk。

2 个答案:

答案 0 :(得分:191)

没关系。 pk更独立于实际的主键字段,即您不必关心主键字段是id还是object_id还是其他。

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

答案 1 :(得分:10)

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

%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。三分之一微秒的时间对网络来说毫无用处。