2010-04-30 19 views
22

Genel bir ilişkiye sahip bir modelim var:App bir Django modeli nasıl alınır?

TrackedItem --- genericrelation ---> any model 

İlk modelden, izlenen öğeden genel olarak elde etmek istiyorum.

Bunu değiştirmeden herhangi bir model üzerinde yapabilmem gerekir.

Bunu yapmak için içerik türünü ve nesne kimliğini almam gerekiyor. Model örneğine sahip olduğumdan, ancak nesne türünü aldığımdan nesne kimliğini almak kolaydır: ContentType.object.filter, modeli (yalnızca content_object.__class__.__name__ olan) ve app_label'i gerektirir.

Modelin güvenilir bir şekilde nasıl uygulanacağına dair bir fikrim yok.

Şimdilik app = content_object.__module__.split(".")[0]'yi yapıyorum, ancak django katkı uygulamalarıyla çalışmıyor.

cevap

28

Sadece ContentType'ı almak için uygulamayı veya modelini almak gerekmez sadece bunu yapmak için kullanışlı bir yöntem var: Adı rağmen

ContentType.objects.get_for_model(myobject) 

, her iki modelin sınıflar için çalışıyor ve örnekler.

+3

Bu, _meta'yı kullanmaktan daha iyi bir çözümdür. – Wogan

+8

Bu mu? Bu veritabanına çarpmadı mı? – meshy

+1

@meshy yes ama django ContentType, yöneticisi üzerinde bir önbellek kullanır, bu nedenle model başına yalnızca bir kez sorgular. – dalore

75

app_label herhangi bir model _meta özniteliği bir nitelik olarak kullanılabilir. -

from django.contrib.auth.models import User 
print User._meta.app_label 
# The object name is also available 
print User._meta.object_name 
0

Sen dahili içinde ContentType sınıf

from django.contrib.contenttypes.models import ContentType 
from django.contrib.auth.models import User 

user_obj = User.objects.create() 
obj_content_type = ContentType.objects.get_for_model(user_obj) 

print(obj_content_type.app_label) 
# u'auth' 
print(obj_content_type.model) 
# u'user' 

Bu özel olarak tanımlanmaktadır _meta özelliklerini kullanarak daha iyi bir yaklaşım saygıdır kullanarak nesneden hem app_label ve model alabilirsiniz.