2010-04-30 2 views
22

J'ai un modèle avec une relation générique:Comment obtenir l'app d'un modèle Django?

TrackedItem --- genericrelation ---> any model 

Je voudrais être en mesure d'obtenir génériquement, à partir du modèle initial, l'élément suivi.

Je devrais pouvoir le faire sur n'importe quel modèle sans le modifier.

Pour ce faire, je dois obtenir le type de contenu et l'identifiant de l'objet. Obtenir l'ID de l'objet est facile car j'ai l'instance du modèle, mais obtenir le type de contenu n'est pas: ContentType.object.filter nécessite le modèle (qui est juste content_object.__class__.__name__) et l'app_label.

Je n'ai aucune idée de comment obtenir de manière fiable l'application dans laquelle un modèle est.

Pour l'instant, je fais app = content_object.__module__.split(".")[0], mais cela ne fonctionne pas avec les applications django contrib.

Répondre

28

Vous n'avez pas besoin d'obtenir l'application ou d'un modèle juste pour obtenir le contenttype - il y a une méthode pratique pour faire exactement cela:

ContentType.objects.get_for_model(myobject) 

Malgré son nom, cela fonctionne pour les deux classes de modèle et instances.

+3

Ceci est une meilleure solution que l'utilisation de _meta. – Wogan

+8

Est-ce? Cela ne frappe-t-il pas la base de données? – meshy

+1

@meshy yes mais django ContentType utilise un cache sur son gestionnaire pour qu'il ne demande qu'une seule requête par modèle. – dalore

75

Le app_label est disponible en tant qu'attribut sur l'attribut _meta de n'importe quel modèle.

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

Vous pouvez obtenir les deux app_label et model de votre objet en utilisant la classe

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' 

intégré ContentType Ceci est un meilleur respect de l'approche de l'utilisation des propriétés _meta qui sont définies comme privées.