Запити Джанго - id vs pk


203

При написанні запитів на django можна використовувати обидва id / pk як параметри запиту.

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

Я знаю, що pk означає первинний ключ і є лише ярликом, згідно документації django. Однак незрозуміло, коли слід використовувати id або pk.


Ось що відповідна docmentation: дляid і дляpk
Lutz Prechelt


Хочете дізнатися, чи є щось більше до цього docs.djangoproject.com/en/1.11/topics/db/queries/…
Раджан Чаухан

Перевірте оновлену версію тут docs.djangoproject.com/en/2.2/topics/db/models/…
Tessaracter

Відповіді:


224

Це не має значення. pkбільш незалежною від поля фактичного первинного ключа тобто вам не потрібно піклуватися чи називається полем первинного ключа idабо object_idабо будь-який інший .

Він також забезпечує більшу узгодженість, якщо у вас є моделі з різними полями первинного ключа.


34
Так. Просто використовуйте pk. Завжди.
cethegeek

47
idтакож є вбудованою функцією в Python, я вважаю за краще використовувати pk через це.
Тьєррі Лам

5
Так, pkбажано. Дивіться документацію вбудованої функціїid в стандартній бібліотеці Python. (
Те

26

У проектах Django, де я знаю, що pkзавжди повертається, idя вважаю за краще використовувати, idколи він не стикається з id()функцією (скрізь, крім імен змінних). Причиною цього є те, що pkце властивість, яка в 7 разів повільніше, ніж idпотрібен час для пошуку pkімені атрибута в 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)

Ось відповідний код Джанго:

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)

Це дійсно рідкісний випадок, коли мені потрібно використовувати змінну на ім'я pk. Я вважаю за краще використовувати щось більш багатослівне, як user_idзамість pk.

Дотримуватися тієї ж конвенції є кращим у всьому проекті. У вашому випадку idце ім'я параметра, а не властивість, тому різниці в таймінгах майже немає. Назви параметрів не суперечать імені вбудованої id()функції, тому тут безпечно використовувати id.

Підводячи підсумок, ви вирішите вибрати, чи використовувати ім'я поля idчи pkярлик. Якщо ви не розробляєте бібліотеку для Django і використовуєте автоматичні поля первинного ключа для всіх моделей, це безпечно використовувати idвсюди, що іноді відбувається швидше. З іншого боку, якщо ви хочете отримати універсальний доступ до (ймовірно, спеціальних) полів первинного ключа, тоді використовуйте pkвсюди. Третина мікросекунди - це нічого для Інтернету.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.