2010-01-14 28 views
43

Nói my_instance là của mô hình MyModel.
Tôi đang tìm kiếm một cách tốt để làm:django: cách thực hành tốt nhất để lấy mô hình từ một phiên bản của mô hình đó

my_model = get_model_for_instance(my_instance) 

tôi đã không tìm thấy bất kỳ cách nào thực sự trực tiếp để làm điều này. Cho đến nay tôi đã đưa ra điều này:

from django.db.models import get_model 

my_model = get_model(my_instance._meta.app_label, my_instance.__class__.__name__) 

Điều này có được chấp nhận không? Nó thậm chí là một cách chắc chắn, cách thực hành tốt nhất để làm điều đó?
Ngoài ra còn có _meta.object_name có vẻ như cung cấp giống như __class__.__name__. Phải không? Tốt hơn hay tệ hơn? Nếu vậy, tại sao?

Ngoài ra, làm cách nào để biết tôi đang nhận đúng mô hình nếu nhãn ứng dụng xảy ra nhiều lần trong phạm vi dự án, ví dụ: 'auth' từ 'django.contrib.auth' và cho phép đó cũng có 'myproject.auth'?
Trường hợp này có khiến get_model không đáng tin cậy không?

Cảm ơn mọi gợi ý/con trỏ và chia sẻ kinh nghiệm!

+3

'__class__' tuyệt đối ** phải ** là lớp cho cá thể. Không có sự mơ hồ có thể xảy ra. Đó là cách Python hoạt động. Bạn hỏi gì? –

+0

Vâng, tôi có một số giới hạn của sự hiểu biết ở đây. Với tôi, sự mơ hồ là có thể có nhiều hơn một nhãn hiệu ứng dụng/tên lớp kết hợp, sống trong các mô-đun khác nhau. Tuy nhiên, get_model không nhận được mô đun như đầu vào. Vì vậy, mô hình nó sẽ cung cấp? Điều khác là tôi không hiểu Object_name là gì, vì nó trả về cùng chuỗi với '__class __.__ name__', và có bao nhiêu người chọn một trong hai cái đó để sử dụng trong' get_model' hoặc ở nơi khác. Cảm ơn! – Geradeausanwalt

Trả lời

69
my_model = type(my_instance) 

Để chứng minh điều đó, bạn có thể tạo ví dụ khác:

my_new_instance = type(my_instance)() 

Đây là lý do tại sao không có cách nào trực tiếp để làm việc đó, bởi vì đối tượng trăn đã có tính năng này.

cập nhật ...

tôi thích marcinn's response sử dụng type(x). Điều này giống với câu trả lời ban đầu được sử dụng (x.__class__), nhưng tôi thích sử dụng các chức năng hơn để truy cập các thông tin kỳ diệu. Theo cách này, tôi thích sử dụng vars(x) tới x.__dict__, len(x) đến x.__len__ và cứ tiếp tục như vậy.

cập nhật 2 ...

Đối với trường hợp trả chậm (được đề cập bởi @Cerin trong ý kiến), bạn có thể truy cập vào các lớp học ban đầu qua instance._meta.proxy_for_model.

+2

Điều này không làm việc với trường hợp hoặc trường hợp bị trì hoãn từ truy vấn bằng cách sử dụng 'only()'. – Cerin

19
my_new_instance = type(my_instance)() 
Các vấn đề liên quan