60

Let's say I am in the save code. How can I obtain the model's name or the content type of the object, and use it?

from django.db import models

class Foo(models.Model):
    ...
    def save(self):
        I am here....I want to obtain the model_name or the content type of the object

This code works, but I have to know the model_name:

import django.db.models
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get(model=model_name)
model = content_type.model_class()
Seitaridis
  • 4,459
  • 9
  • 53
  • 85

3 Answers3

109

You can get the model name from the object like this:

self.__class__.__name__

If you prefer the content type, you should be able to get that like this:

from django.contrib.contenttypes.models import ContentType
ContentType.objects.get_for_model(self)
Nicolò Gasparini
  • 2,228
  • 2
  • 24
  • 53
gravelpot
  • 1,677
  • 1
  • 14
  • 20
  • If you have a database browser tool you can see that a django_content_type is created. It contains some fields, like name, app_label and model. I need to obtain that model information from the class I am in. – Seitaridis Feb 01 '11 at 14:20
  • 1
    The model field is a lowercase string and it is derived from the class name. – Seitaridis Feb 01 '11 at 14:22
  • 1
    Then do something like 'ct = ContentType.objects.get_for_model(self)', followed by 'return ct.app_label' or whichever ContentType attribute you need. – gravelpot Feb 01 '11 at 14:23
  • 1
    Or just lowercase the class name to get the content type, whichever you prefer...'print self.__class__.__name__.lower()' – gravelpot Feb 01 '11 at 14:25
  • Thank you. ContentType.objects.get_for_model(self) did the trick – Seitaridis Feb 01 '11 at 14:53
  • 3
    The solution via `ContentType` requires an additional SQL request. – tobltobs May 26 '16 at 17:38
11

The method get_for_model does some fancy stuff, but there are some cases when it's better to not use that fancy stuff. In particular, say you wanted to filter a model that linked to ContentType, maybe via a generic foreign key?? The question here was what to use for model_name in:

content_type = ContentType.objects.get(model=model_name)

Use Foo._meta.model_name, or if you have a Foo object, then obj._meta.model_name is what you're looking for. Then, you can do things like

Bar.objects.filter(content_type__model=Foo._meta.model_name)

This is an efficient way to filter the Bar table to return you objects which link to the Foo content type via a field named content_type.

AlanSE
  • 2,597
  • 2
  • 29
  • 22
4

Using gravelpot's answer, to give a direct answer to the OP's question:

We can get the object's class through instance.__class__ and then pass it to the get_for_model function:

from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(instance.__class__)
Pablo Guerrero
  • 936
  • 1
  • 12
  • 22