Джанго запросы - идентификатор против ПК

205

При написании django-запросов можно использовать оба id / pk в качестве параметров запроса.

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

Я знаю, что pk обозначает Primary Key и является просто ярлыком, согласно документации django. Однако неясно, когда следует использовать id или pk.

Искусство
источник
Вот соответствующая документация: дляid и дляpk
Лутц Пречелт
Возможный дубликат В чем разница между Model.id и Model.pk в django?
Трэвис,
Хотите знать, что-то еще, docs.djangoproject.com/en/1.11/topics/db/queries/…
Раджан Чаухан
Проверьте обновленную версию здесь docs.djangoproject.com/en/2.2/topics/db/models/...
Tessaracter

Ответы:

224

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

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

Феликс Клинг
источник
35
Ага. Просто используйте ПК. Всегда.
cethegeek
48
idэто также встроенная функция в Python, поэтому я предпочитаю использовать pk.
Тьерри Лэм
6
Да, 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)

Вот соответствующий код Django:

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везде. Треть микросекунды - ничто для сети.

utapyngo
источник