Django查询 - id vs pk

Art*_*Art 188 django orm primary-key

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

Object.objects.get(id=1)
Object.objects.get(pk=1)
Run Code Online (Sandbox Code Playgroud)

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

Fel*_*ing 205

没关系.pk更独立于实际的主键字段即你不必在意的主键字段是否被称为idobject_id或什么的.

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

  • `id`也是Python中的内置函数,因此我更喜欢使用pk. (44认同)
  • 是的.只需使用PK.总是. (26认同)
  • 是的,``pk``更可取.请参阅Python标准库中的[内置函数``id``文档](https://docs.python.org/3.5/library/functions.html#id).(它是[在Python 2中相同](https://docs.python.org/2.7/library/functions.html#id).) (5认同)

uta*_*ngo 16

在我知道pk总是返回的Django项目中,当它不与函数冲突时(除了变量名之外的任何地方),id我更喜欢使用idid().这样做的原因是,这pk是一个比id查找pk属性名称需要时间慢7倍的属性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)
Run Code Online (Sandbox Code Playgroud)

这是相关的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)
Run Code Online (Sandbox Code Playgroud)

当我需要使用名为的变量时,这是一种罕见的情况pk.我更喜欢使用更冗长的东西,user_id而不是pk.

遵循相同的惯例在整个项目中是可取的.在您的情况下id是参数名称,而不是属性,因此时间几乎没有差异.参数名称不与内置id()函数的名称冲突,因此id在此处使用是安全的.

总而言之,您可以选择是使用字段名称id还是使用pk快捷方式.如果您没有为Django开发库并为所有模型使用自动主键字段,则可以安全地id在任何地方使用,这有时会更快.另一方面,如果您想要(通常是自定义的)主键字段的通用访问,那么pk随处使用.微秒的三分之一对于网络来说并不算什么.