Requêtes Django - ID vs PK

205

Lors de l'écriture de requêtes django, on peut utiliser à la fois id / pk comme paramètres de requête.

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

Je sais que pk représente la clé primaire et n'est qu'un raccourci, selon la documentation de django. Cependant, il n'est pas clair quand il faut utiliser id ou pk.

Art
la source
Voici cette docmentation respective: pourid et pourpk
Lutz Prechelt
Vous voulez savoir si quelque chose est plus que ça docs.djangoproject.com/en/1.11/topics/db/queries/…
Rajan Chauhan
Vérifiez la version mise à jour ici docs.djangoproject.com/en/2.2/topics/db/models/…
Tessaracter

Réponses:

224

Ça n'a pas d'importance. pkest plus indépendant du champ de clé primaire réelle à dire que vous n'avez pas besoin de prendre soin si le champ de clé primaire est appelée idou object_idou autre.

Il offre également plus de cohérence si vous disposez de modèles avec différents champs de clé primaire.

Felix Kling
la source
35
Oui. Utilisez simplement pk. Toujours.
cethegeek
48
idest également une fonction intégrée en Python, je préfère utiliser pk à cause de cela.
Thierry Lam
6
Oui, pkc'est préférable. Voir la documentation de la fonction intégréeid dans la bibliothèque standard Python. (C'est la même chose dans Python 2. )
Lutz Prechelt
26

Dans les projets Django où je sais que ça pkrevient toujours, idje préfère utiliser idquand ça ne heurte pas la id()fonction (partout sauf les noms de variables). La raison en est qu'il pks'agit d'une propriété 7 fois plus lente que la idrecherche du pknom d'attribut en temps 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)

Voici le code Django pertinent:

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)

C'est vraiment un cas rare lorsque j'ai besoin d'utiliser une variable nommée pk. Je préfère utiliser quelque chose de plus verbeux, comme user_idau lieu de pk.

Suivre la même convention est préférable pour l'ensemble du projet. Dans votre cas, il ids'agit d'un nom de paramètre, et non d'une propriété, il n'y a donc presque aucune différence de synchronisation. Les noms de paramètres ne sont pas en conflit avec le nom de la id()fonction intégrée, il est donc sûr de l'utiliser idici.

Pour résumer, c'est à vous de choisir d'utiliser le nom du champ idou le pkraccourci. Si vous ne développez pas de bibliothèque pour Django et utilisez des champs de clé primaire automatiques pour tous les modèles, il est sûr de les utiliser idpartout, ce qui est parfois plus rapide. D'un autre côté, si vous souhaitez un accès universel aux champs de clé primaire (probablement personnalisés), utilisez-les pkpartout. Un tiers de microseconde n'est rien pour le web.

utapyngo
la source