2012-04-27 27 views
13

Có thể lấy mô hình liên quan của khóa ngoài thông qua trường khóa ngoài không?Django Foreign Key: lấy mô hình liên quan?

Ví dụ, nếu tôi có 3 mô hình:

class ModelA(models.Model) 
    field1 = models.CharField(max_length=10) 

class ModelB(models.Model) 
    field1 = models.CharField(max_length=10) 

class ModelC(models.Model) 
    field1 = models.CharField(max_length=10) 
    field2 = models.ForeignKey(ModelA) 
    field3 = models.ForeignKey(ModelB) 

và tôi muốn làm:

for field in ModelC._meta.fields: 
    if field.get_internal_type() == "ForeignKey": 
     #get the related model for field e.g. ModelA or ModelB 

Đây có phải là có thể sử dụng chỉ là mô hình bản thân chứ không phải là trường hợp của các mô hình?

Trả lời

19

Nếu ModelA có một lĩnh vực FK có tên là "foo", thì đây là cách bạn có thể nhận được các mô hình liên quan:

ModelA._meta.get_field('foo').rel.to 

Với mã của bạn, nó sẽ trông giống như:

for field in ModelC._meta.fields: 
    if field.get_internal_type() == "ForeignKey": 
     print field.rel.to 

Nếu tìm thấy nó bằng cách sử dụng hoàn thành tab trong trình bao dài trước đây, nó vẫn hoạt động. Bạn có thể muốn học cách sử dụng trình bao để đảo ngược các công cụ kỹ sư như thế.

+0

Cập nhật: Trong phiên bản mới phát hành Django 2.0, có vẻ như "rel" không còn một lĩnh vực ForeignKey. Bạn có thể thử: 'ModelA._meta.get_field ('foo'). Related_model'. Tôi tìm ra điều này bằng cách gõ "tab" để tự động hoàn thành trong dòng lệnh. –

0

Khi cố gắng trích xuất các quan hệ như thế này, tôi sử dụng rất nhiều thử nghiệm dòng lệnh. Mẫu chung tôi sử dụng là _=starting_point.<chained_attributes>;pprint((_, dir(_))). Ví dụ:

_=ModelC;pprint((_, dir(_))) 
_=ModelC.field2;pprint((_, dir(_))) 
_=ModelC.field2.field;pprint((_, dir(_))) 
_=ModelC.field2.field.rel;pprint((_, dir(_))) 
_=ModelC.field2.field.rel.to;pprint((_, dir(_))) 

(Bạn sẽ cần phải làm from pprint import pprint đầu tiên, một cách tự nhiên.) Điều đó cho phép tôi thử nghiệm với việc thêm/gỡ bỏ các thuộc tính cho đến khi một tìm mục Tôi muốn ... khi nhìn thấy rõ ràng những gì tôi đã có và những gì có sẵn ở cấp độ tiếp theo. Từ đó, tôi nhận được ModelC.field2.field.rel.to == ModelA. Có thể sử dụng cùng một mẫu cơ sở để khám phá các mối quan hệ ngược lại, mối quan hệ nhiều-nhiều, bắt đầu với một cá thể chứ không phải là lớp, v.v.

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