2014-07-22 16 views
9

Giả sử tôi có một kiểu như thế này.Cách thức truy cập khóa ngoài của Django hoạt động

class Job(models.Model): 
    client = models.ForeignKey(Contacts, null=True) 

và cho phép nói rằng tôi có công việc j. Tôi biết tôi có thể truy cập vào các khách hàng thuộc j như thế này

j.client 

nhưng cũng là

j.client_id 

Vì vậy, câu hỏi của tôi là làm thế nào để tiếp cận công việc j.client?

Liệu django store client__id sau đó khi j.client được gọi nó là một truy vấn để tìm đối tượng chính xác?

Hoặc tham chiếu đối tượng được lưu trữ đến j và truy cập client__id có nhận được id từ đối tượng Địa chỉ liên hệ không?

Tôi đã nhìn xung quanh mã nguồn một chút nhưng không thể tìm thấy câu trả lời cho câu hỏi của tôi

+0

bản sao có thể có của [Khi nào Django tra cứu khóa chính của khóa ngoại?] (Http://stackoverflow.com/questions/13631211/when-does-django-look-up-the-primary-key-of -nên-phím) –

Trả lời

8

này được giải thích trong tài liệu:
https://docs.djangoproject.com/en/dev/ref/models/fields/#database-representation

Trong cơ sở dữ liệu chỉ có client_id trường (gạch duy nhất)

Trên ví dụ mẫu, bạn sẽ có thuộc tính client, khi bạn truy cập vào nó, điều này sẽ khiến Django tải đối tượng liên quan từ db và khởi tạo như một thể hiện mô hình khác.

Bạn cũng sẽ có thuộc tính client_id (một dấu gạch dưới) có giá trị khóa chính của đối tượng liên quan, như được lưu trữ trong trường db.

Khi làm các truy vấn ORM bạn có thể sử dụng cú pháp client__id (double gạch dưới) để tra cứu chống lại các lĩnh vực trên mô hình có liên quan, ví dụ như bạn cũng có thể làm client__name nếu Client mô hình đã có một lĩnh vực name. Điều này sẽ trở thành một truy vấn SQL JOIN trên cả hai mô hình.

ví dụ

Job.objects.get(client__id=1) 
Job.objects.filter(client__name='John') 

client = Client.objects.get(pk=1) 
Job.objects.get(client=client) 
+0

Tôi đã nhận thấy lỗi của mình và đã chỉnh sửa câu hỏi để phản ánh chính xác quyền truy cập. Tuyệt vời đây là xác nhận tôi đang tìm kiếm. Tôi nghi ngờ đây là trường hợp, cảm ơn bạn đời! –

2

j.client cung cấp cho bạn các đối tượng models.Model. Bạn có thể truy cập các thuộc tính của nó như ...

client = j.client 

id = client.id 
name = client.name 

Nhưng không nên có trường j.client__id. Bạn nên sử dụng j.client.id để lấy trường id. Mặc dù bạn có thể sử dụng trường j.client__id để thực hiện các bộ lọc và như vậy.

Vì vậy,

id = j.client.id # good 
id = j.client__id # bad 

job = Job.objects.get(client__id=1) # good 
job = Job.objects.get(client.id=1) # bad 
+0

Xin lỗi tôi không có ý định đặt thêm _ Có một trường client_id thử nó cho chính mình –

+0

Từ tài liệu của Django - "Phía sau hậu trường, Django nối" _id "vào tên trường để tạo cơ sở dữ liệu tên cột dọc. ". –

+0

Và tôi không chắc chắn tại sao một người nào đó sẽ trả lời câu hỏi của tôi dựa trên câu hỏi được đánh sai. –

9

Những gì bạn có thể nói về là clientclient_id (gạch duy nhất).

Thuộc tính client_id là thuộc tính thông thường (số nguyên). Đây là khóa ngoài được lưu vào cơ sở dữ liệu.Bạn sẽ chỉ thấy một cột client_id trong cơ sở dữ liệu, mặc dù bạn chỉ định ForeignKeyclient.

Thuộc tính client là một đối tượng mô tả đối tượng. Nó là một lớp đặc biệt ghi đè các phương thức __get____set__, do đó, các thiết lập và truy cập các thuộc tính đó gọi ra các phương thức của lớp đó. Đây là phép thuật cho phép bạn truy cập vào cá thể mô hình thực tế liên quan. __get__ sẽ truy xuất phiên bản mẫu đúng từ cơ sở dữ liệu nếu nó chưa được tải, dựa trên thuộc tính client_id. __set__ cũng sẽ đặt thuộc tính client_id thành khóa chính của đối tượng liên quan, để client_id luôn được cập nhật.

Lưu ý rằng thuộc tính này cũng có sẵn trong tra cứu truy vấn và khá tiện dụng. Ví dụ, nếu bạn có chỉ là khóa chính của một đối tượng nước ngoài, và không phải là mô hình ví dụ bản thân, các truy vấn sau trông rất giống:

job = Job.objects.filter(client__id=pk) 
job = Job.objects.filter(client_id=pk) 

Tuy nhiên, bên dưới truy vấn đầu tiên truy cập một thuộc tính trên đối tượng có liên quan (double gạch dưới) và thực hiện OUTER JOIN. Truy vấn thứ hai chỉ bao giờ truy cập thuộc tính cục bộ, do đó không phải thực hiện tuyên bố OUTER JOIN và hiệu suất lưu.

+0

Yep Tôi đã thay đổi câu hỏi của mình, nhận thấy lỗi sau một phút tôi đăng. Các bạn quá nhanh với tôi>.

Các vấn đề liên quan