Consultas de Django - id vs pk

204

Al escribir consultas django, uno puede usar tanto id / pk como parámetros de consulta.

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

Sé que pk significa Clave primaria y es solo un acceso directo, según la documentación de django. Sin embargo, no está claro cuándo se debe usar id o pk.

Arte
fuente
Aquí está esa documentación respectiva: porid y parapk
Lutz Prechelt
¿Quieres saber si hay algo más? Docs.djangoproject.com/en/1.11/topics/db/queries/…
Rajan Chauhan
Verifique la versión actualizada aquí docs.djangoproject.com/en/2.2/topics/db/models/…
Tessaracter el

Respuestas:

224

No importa. pkes más independiente del campo de clave principal real, es decir que no es necesario preocuparse de si el campo de clave principal se llama ido object_idlo que sea.

También proporciona más coherencia si tiene modelos con diferentes campos de clave principal.

Felix Kling
fuente
34
Sí. Solo usa pk. Siempre.
cethegeek
47
idtambién es una función incorporada en Python, prefiero usar pk por eso.
Thierry Lam el
55
Si, pkes preferible. Consulte la documentación de la función incorporadaid en la biblioteca estándar de Python. (Es lo mismo en Python 2. )
Lutz Prechelt el
26

En los proyectos de Django donde sé que pksiempre regresa id, prefiero usarlos idcuando no entran en conflicto con la id()función (en todas partes, excepto los nombres de variables). La razón de esto es que pkes una propiedad que es 7 veces más lenta que iddesde que lleva tiempo buscar el pknombre del atributo 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)

Aquí está el código Django relevante:

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)

Es realmente un caso raro cuando necesito usar una variable llamada pk. Prefiero usar algo más detallado, como en user_idlugar depk .

Seguir la misma convención es preferible en todo el proyecto. En su caso, ides un nombre de parámetro, no una propiedad, por lo que casi no hay diferencia en los tiempos. Los nombres de los parámetros no coinciden con el nombre de la id()función incorporada, por lo que es seguro usarid aquí.

En resumen, depende de usted elegir si desea usar el nombre del campo ido el pkacceso directo. Si no está desarrollando una biblioteca para Django y utiliza campos de clave primaria automáticos para todos los modelos, es seguro usarlos en idtodas partes, lo que a veces es más rápido. Por otro lado, si desea acceso universal a los campos de clave primaria (probablemente personalizados), utilícelos en pktodas partes. Un tercio de microsegundo no es nada para la web.

utapyngo
fuente