Django-Abfragen - id vs pk

202

Beim Schreiben von Django-Abfragen kann man beide id / pk als Abfrageparameter verwenden.

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

Ich weiß, dass pk für Primary Key steht und laut Djangos Dokumentation nur eine Abkürzung ist. Es ist jedoch nicht klar, wann man id oder pk verwenden soll.

Kunst
quelle
Hier ist die entsprechende Dokumentation: fürid und fürpk
Lutz Prechelt
Möchten
Rajan Chauhan
Überprüfen Sie die aktualisierte Version hier docs.djangoproject.com/de/2.2/topics/db/models/…
Tessaracter

Antworten:

224

Es spielt keine Rolle. pkist unabhängig von dem Primärschlüsselfeld tatsächlichen dh, ob das Primärschlüsselfeld heißt nicht brauchen zu kümmern idoder object_idoder was auch immer.

Es bietet auch mehr Konsistenz, wenn Sie Modelle mit unterschiedlichen Primärschlüsselfeldern haben.

Felix Kling
quelle
34
Ja. Verwenden Sie einfach pk. Immer.
Cethegeek
47
idist auch eine in Python eingebaute Funktion, deshalb bevorzuge ich die Verwendung von pk.
Thierry Lam
5
Ja, pkist vorzuziehen. Weitere Informationen finden Sie in der Dokumentation der integrierten Funktionid in der Python-Standardbibliothek. (Es ist das gleiche in Python 2. )
Lutz Prechelt
25

In Django-Projekten, von denen ich weiß, dass sie pkimmer zurückkehren, idbevorzuge ich die Verwendung, idwenn sie nicht mit der id()Funktion kollidieren (überall außer Variablennamen). Der Grund dafür ist, dass pkes sich um eine Eigenschaft handelt, die siebenmal langsamer ist als iddie Suche nach pkAttributnamen in 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)

Hier ist der relevante Django-Code:

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 ist wirklich ein seltener Fall, wenn ich eine Variable mit dem Namen verwenden muss pk. Ich bevorzuge es, etwas ausführlicheres zu verwenden, user_idanstatt pk.

Die Befolgung derselben Konvention ist für das gesamte Projekt vorzuziehen. In Ihrem Fall idhandelt es sich um einen Parameternamen, nicht um eine Eigenschaft, sodass sich die Timings kaum unterscheiden. Parameternamen kollidieren nicht mit dem Namen der integrierten id()Funktion, daher ist die Verwendung sicherid hier .

Zusammenfassend liegt es an Ihnen, zu entscheiden, ob Sie den Feldnamen idoder die pkVerknüpfung verwenden möchten. Wenn Sie keine Bibliothek für Django entwickeln und für alle Modelle automatische Primärschlüsselfelder verwenden, können Sie diese idüberall verwenden, was manchmal schneller ist. Wenn Sie andererseits universellen Zugriff auf (wahrscheinlich benutzerdefinierte) Primärschlüsselfelder wünschen, verwenden Sie diese pküberall. Eine Drittel-Mikrosekunde ist nichts für das Web.

utapyngo
quelle