265

When writing django queries one can use both id/pk as query parameters.

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

I know that pk stands for Primary Key and is just a shortcut, according to django's documentation. However it is not clear when one should be using id or pk.

Art
  • 23,747
  • 29
  • 89
  • 101
  • Here is that respective docmentation: [for ``id``](https://docs.djangoproject.com/en/1.9/topics/db/models/#automatic-primary-key-fields) and [for ``pk``](https://docs.djangoproject.com/en/1.9/topics/db/queries/#the-pk-lookup-shortcut) – Lutz Prechelt Mar 23 '16 at 09:18
  • 1
    Possible duplicate of [What's the difference between Model.id and Model.pk in django?](http://stackoverflow.com/questions/22345711/whats-the-difference-between-model-id-and-model-pk-in-django) – Travis Oct 05 '16 at 16:26
  • Want to know if something is more to it https://docs.djangoproject.com/en/1.11/topics/db/queries/#copying-model-instances – Rajan Chauhan Jul 11 '17 at 16:52
  • Check Updated version here https://docs.djangoproject.com/en/2.2/topics/db/models/#automatic-primary-key-fields – Trect Sep 23 '19 at 14:03

2 Answers2

277

It doesn't matter. pk is more independent from the actual primary key field i.e. you don't need to care whether the primary key field is called id or object_id or whatever.

It also provides more consistency if you have models with different primary key fields.

Deepstop
  • 3,627
  • 2
  • 8
  • 21
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 63
    `id` is also a built-in function in Python, I prefer to use pk because of that. – Thierry Lam Oct 23 '10 at 14:05
  • 10
    Yes, ``pk`` is preferable. See the [documentation of built-in function``id``](https://docs.python.org/3.5/library/functions.html#id) in the Python standard library. (It is the [same in Python 2](https://docs.python.org/2.7/library/functions.html#id).) – Lutz Prechelt Mar 23 '16 at 08:17
  • i guess they are talking more about ORM `id` not talking about the python `id` function. – Devang Hingu Dec 22 '22 at 10:53
  • Use pk, since after a while You'll have projects with custom primary keys that aren't named ID, so it can create problems, get used to pk since it always refer to the Primary key field no matter what is the name – BGOPC Jun 24 '23 at 18:55
67

In Django projects where I know that pk always returns id I prefer using id when it does not clash with the id() function (everywhere except variable names). The reason for this is that pk is a property which is 7 times slower than id since it takes time looking up pk attribute name 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)

Here is the relevant 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)

It is really a rare case when I need to use a variable named pk. I prefer using something more verbose, like user_id instead of pk.

Following the same convention is preferable across the whole project. In your case id is a parameter name, not a property, so there is almost no difference in timings. Parameter names do not clash with the name of built-in id() function, so it is safe to use id here.

To sum up, it is up to you to choose whether to use field name id or the pk shortcut. If you are not developing a library for Django and use automatic primary key fields for all models, it is safe to use id everywhere, which is sometimes faster. From the other hand, if you want universal access to (probably custom) primary key fields, then use pk everywhere. A third of a microsecond is nothing for web.

utapyngo
  • 6,946
  • 3
  • 44
  • 65