Django查询- id vs pk

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

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

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

73793 次浏览

没关系。pk更独立于实际的主键字段,即你不需要关心主键字段是被称为id还是object_id或其他什么。

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

在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。三分之一微秒对于网络来说不算什么。