Consultas do Django - id vs pk

203

Ao escrever consultas no django, pode-se usar id / pk como parâmetros de consulta.

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

Eu sei que pk significa Primary Key e é apenas um atalho, de acordo com a documentação do django. No entanto, não está claro quando alguém deve usar id ou pk.

Arte
fonte
Aqui é que respectiva docmentation: paraid e parapk
Lutz Prechelt
Quer saber se algo é mais do que isso docs.djangoproject.com/en/1.11/topics/db/queries/...
Rajan Chauhan
Verifique a versão atualizada aqui docs.djangoproject.com/en/2.2/topics/db/models/…
Tessaracter

Respostas:

224

Não importa. pké mais independente do campo de chave primária real ou seja, você não precisa se preocupar se o campo de chave primária é chamado idou object_idou qualquer outra coisa.

Ele também fornece mais consistência se você tiver modelos com diferentes campos de chave primária.

Felix Kling
fonte
34
Sim. Basta usar pk. Sempre.
Cethegeek
47
idtambém é uma função interna do Python, prefiro usar pk por causa disso.
Thierry Lam
5
Sim, pké preferível. Veja a documentação da funçãoid interna na biblioteca padrão do Python. (É o mesmo em Python 2 ).
Lutz Prechelt 23/03
26

Nos projetos do Django, onde eu sei que pksempre retorna id, prefiro usar idquando ele não entra em conflito com a id()função (em todos os lugares, exceto nomes de variáveis). A razão para isso é que pké uma propriedade 7 vezes mais lenta que ida demora em procurar o pknome do 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)

Aqui está o 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)

É realmente um caso raro quando eu preciso usar uma variável chamada pk. Eu prefiro usar algo mais detalhado, como em user_idvez de pk.

Seguir a mesma convenção é preferível em todo o projeto. No seu caso, idexiste um nome de parâmetro, não uma propriedade; portanto, quase não há diferença nos tempos. Os nomes de parâmetros não se chocam com o nome da id()função interna, portanto, é seguro usá-lo idaqui.

Para resumir, cabe a você escolher se deseja usar o nome do campo idou o pkatalho. Se você não está desenvolvendo uma biblioteca para o Django e usa campos automáticos de chave primária para todos os modelos, é seguro usá-lo em idqualquer lugar, o que às vezes é mais rápido. Por outro lado, se você deseja acesso universal a campos de chave primária (provavelmente personalizados), use em pkqualquer lugar. Um terço de microssegundo não é nada para a web.

utapyngo
fonte