Truy vấn Django - id vs pk


202

Khi viết truy vấn django, người ta có thể sử dụng cả id / pk làm tham số truy vấn.

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

Tôi biết rằng pk là viết tắt của Khóa chính và chỉ là một phím tắt, theo tài liệu của django. Tuy nhiên vẫn chưa rõ khi nào nên sử dụng id hoặc pk.


Đây là tài liệu tương ứng: choidchopk
Lutz Prechelt


Muốn biết nếu có gì đó hơn thế thì docs.djangoproject.com/en/1.11/topics/db/queries/ Kẻ
Rajan Chauhan

Kiểm tra phiên bản cập nhật tại đây docs.djangoproject.com/en/2.2/topics/db/models/ mẹo
Tessaracter

Câu trả lời:


224

Nó không thành vấn đề. pklà độc lập hơn từ các trường tiểu học trọng thực tế tức là bạn không cần phải quan tâm xem trường khóa chính được gọi là idhay object_idhoặc bất cứ điều gì.

Nó cũng cung cấp tính nhất quán hơn nếu bạn có các mô hình với các trường khóa chính khác nhau.


34
Vâng. Chỉ cần sử dụng pk. Luôn luôn.
cethegeek

47
idcũng là một hàm tích hợp trong Python, tôi thích sử dụng pk hơn vì điều đó.
Thierry Lam

5
Có, pklà thích hợp hơn. Xem tài liệu về hàm dựng sẵn trongid thư viện chuẩn Python. (Nó giống với Python 2. )
Lutz Prechelt

25

Trong các dự án Django nơi tôi biết rằng pkluôn trả về idtôi thích sử dụng idkhi nó không xung đột với id()hàm (ở mọi nơi trừ tên biến). Lý do cho điều này là pkmột thuộc tính chậm hơn 7 lần so với idviệc mất thời gian tìm kiếm pktên thuộc tính 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)

Đây là mã Django có liên quan:

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)

Đây thực sự là một trường hợp hiếm hoi khi tôi cần sử dụng một biến có tên pk. Tôi thích sử dụng một cái gì đó dài dòng hơn, như user_idthay vì pk.

Theo cùng một quy ước là tốt hơn trên toàn bộ dự án. Trong trường hợp của bạn idlà một tên tham số, không phải là một thuộc tính, vì vậy hầu như không có sự khác biệt về thời gian. Tên tham số không xung đột với tên của id()hàm tích hợp, vì vậy nó an toàn khi sử dụng idở đây.

Để tổng hợp, tùy thuộc vào bạn chọn sử dụng tên trường idhoặc pkphím tắt. Nếu bạn không phát triển thư viện cho Django và sử dụng các trường khóa chính tự động cho tất cả các mô hình, thì có thể sử dụng idở mọi nơi, điều này đôi khi nhanh hơn. Mặt khác, nếu bạn muốn truy cập toàn cầu vào các trường khóa chính (có thể tùy chỉnh), thì hãy sử dụng pkở mọi nơi. Một phần ba của một phần triệu giây là không có gì cho web.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.