contenttypes.txt 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. ==========================
  2. The contenttypes framework
  3. ==========================
  4. .. module:: django.contrib.contenttypes
  5. :synopsis: Provides generic interface to installed models.
  6. Django includes a :mod:`~django.contrib.contenttypes` application that can
  7. track all of the models installed in your Django-powered project, providing a
  8. high-level, generic interface for working with your models.
  9. Overview
  10. ========
  11. At the heart of the contenttypes application is the
  12. :class:`~django.contrib.contenttypes.models.ContentType` model, which lives at
  13. ``django.contrib.contenttypes.models.ContentType``. Instances of
  14. :class:`~django.contrib.contenttypes.models.ContentType` represent and store
  15. information about the models installed in your project, and new instances of
  16. :class:`~django.contrib.contenttypes.models.ContentType` are automatically
  17. created whenever new models are installed.
  18. Instances of :class:`~django.contrib.contenttypes.models.ContentType` have
  19. methods for returning the model classes they represent and for querying objects
  20. from those models. :class:`~django.contrib.contenttypes.models.ContentType`
  21. also has a :ref:`custom manager <custom-managers>` that adds methods for
  22. working with :class:`~django.contrib.contenttypes.models.ContentType` and for
  23. obtaining instances of :class:`~django.contrib.contenttypes.models.ContentType`
  24. for a particular model.
  25. Relations between your models and
  26. :class:`~django.contrib.contenttypes.models.ContentType` can also be used to
  27. enable "generic" relationships between an instance of one of your
  28. models and instances of any model you have installed.
  29. Installing the contenttypes framework
  30. =====================================
  31. The contenttypes framework is included in the default
  32. :setting:`INSTALLED_APPS` list created by ``django-admin.py startproject``,
  33. but if you've removed it or if you manually set up your
  34. :setting:`INSTALLED_APPS` list, you can enable it by adding
  35. ``'django.contrib.contenttypes'`` to your :setting:`INSTALLED_APPS` setting.
  36. It's generally a good idea to have the contenttypes framework
  37. installed; several of Django's other bundled applications require it:
  38. * The admin application uses it to log the history of each object
  39. added or changed through the admin interface.
  40. * Django's :mod:`authentication framework <django.contrib.auth>` uses it
  41. to tie user permissions to specific models.
  42. .. currentmodule:: django.contrib.contenttypes.models
  43. The ``ContentType`` model
  44. =========================
  45. .. class:: ContentType
  46. Each instance of :class:`~django.contrib.contenttypes.models.ContentType`
  47. has three fields which, taken together, uniquely describe an installed
  48. model:
  49. .. attribute:: app_label
  50. The name of the application the model is part of. This is taken from
  51. the :attr:`app_label` attribute of the model, and includes only the
  52. *last* part of the application's Python import path;
  53. "django.contrib.contenttypes", for example, becomes an
  54. :attr:`app_label` of "contenttypes".
  55. .. attribute:: model
  56. The name of the model class.
  57. .. attribute:: name
  58. The human-readable name of the model. This is taken from the
  59. :attr:`verbose_name <django.db.models.Field.verbose_name>`
  60. attribute of the model.
  61. Let's look at an example to see how this works. If you already have
  62. the :mod:`~django.contrib.contenttypes` application installed, and then add
  63. :mod:`the sites application <django.contrib.sites>` to your
  64. :setting:`INSTALLED_APPS` setting and run ``manage.py migrate`` to install it,
  65. the model :class:`django.contrib.sites.models.Site` will be installed into
  66. your database. Along with it a new instance of
  67. :class:`~django.contrib.contenttypes.models.ContentType` will be
  68. created with the following values:
  69. * :attr:`~django.contrib.contenttypes.models.ContentType.app_label`
  70. will be set to ``'sites'`` (the last part of the Python
  71. path "django.contrib.sites").
  72. * :attr:`~django.contrib.contenttypes.models.ContentType.model`
  73. will be set to ``'site'``.
  74. * :attr:`~django.contrib.contenttypes.models.ContentType.name`
  75. will be set to ``'site'``.
  76. .. _the verbose_name attribute: ../model-api/#verbose_name
  77. Methods on ``ContentType`` instances
  78. ====================================
  79. Each :class:`~django.contrib.contenttypes.models.ContentType` instance has
  80. methods that allow you to get from a
  81. :class:`~django.contrib.contenttypes.models.ContentType` instance to the
  82. model it represents, or to retrieve objects from that model:
  83. .. method:: ContentType.get_object_for_this_type(**kwargs)
  84. Takes a set of valid :ref:`lookup arguments <field-lookups-intro>` for the
  85. model the :class:`~django.contrib.contenttypes.models.ContentType`
  86. represents, and does
  87. :meth:`a get() lookup <django.db.models.query.QuerySet.get>`
  88. on that model, returning the corresponding object.
  89. .. method:: ContentType.model_class()
  90. Returns the model class represented by this
  91. :class:`~django.contrib.contenttypes.models.ContentType` instance.
  92. For example, we could look up the
  93. :class:`~django.contrib.contenttypes.models.ContentType` for the
  94. :class:`~django.contrib.auth.models.User` model::
  95. >>> from django.contrib.contenttypes.models import ContentType
  96. >>> user_type = ContentType.objects.get(app_label="auth", model="user")
  97. >>> user_type
  98. <ContentType: user>
  99. And then use it to query for a particular
  100. :class:`~django.contrib.auth.models.User`, or to get access
  101. to the ``User`` model class::
  102. >>> user_type.model_class()
  103. <class 'django.contrib.auth.models.User'>
  104. >>> user_type.get_object_for_this_type(username='Guido')
  105. <User: Guido>
  106. Together,
  107. :meth:`~django.contrib.contenttypes.models.ContentType.get_object_for_this_type`
  108. and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` enable
  109. two extremely important use cases:
  110. 1. Using these methods, you can write high-level generic code that
  111. performs queries on any installed model -- instead of importing and
  112. using a single specific model class, you can pass an ``app_label`` and
  113. ``model`` into a
  114. :class:`~django.contrib.contenttypes.models.ContentType` lookup at
  115. runtime, and then work with the model class or retrieve objects from it.
  116. 2. You can relate another model to
  117. :class:`~django.contrib.contenttypes.models.ContentType` as a way of
  118. tying instances of it to particular model classes, and use these methods
  119. to get access to those model classes.
  120. Several of Django's bundled applications make use of the latter technique.
  121. For example,
  122. :class:`the permissions system <django.contrib.auth.models.Permission>` in
  123. Django's authentication framework uses a
  124. :class:`~django.contrib.auth.models.Permission` model with a foreign
  125. key to :class:`~django.contrib.contenttypes.models.ContentType`; this lets
  126. :class:`~django.contrib.auth.models.Permission` represent concepts like
  127. "can add blog entry" or "can delete news story".
  128. The ``ContentTypeManager``
  129. --------------------------
  130. .. class:: ContentTypeManager
  131. :class:`~django.contrib.contenttypes.models.ContentType` also has a custom
  132. manager, :class:`~django.contrib.contenttypes.models.ContentTypeManager`,
  133. which adds the following methods:
  134. .. method:: clear_cache()
  135. Clears an internal cache used by
  136. :class:`~django.contrib.contenttypes.models.ContentType` to keep track
  137. of models for which it has created
  138. :class:`~django.contrib.contenttypes.models.ContentType` instances. You
  139. probably won't ever need to call this method yourself; Django will call
  140. it automatically when it's needed.
  141. .. method:: get_for_id(id)
  142. Lookup a :class:`~django.contrib.contenttypes.models.ContentType` by ID.
  143. Since this method uses the same shared cache as
  144. :meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`,
  145. it's preferred to use this method over the usual
  146. ``ContentType.objects.get(pk=id)``
  147. .. method:: get_for_model(model[, for_concrete_model=True])
  148. Takes either a model class or an instance of a model, and returns the
  149. :class:`~django.contrib.contenttypes.models.ContentType` instance
  150. representing that model. ``for_concrete_model=False`` allows fetching
  151. the :class:`~django.contrib.contenttypes.models.ContentType` of a proxy
  152. model.
  153. .. method:: get_for_models(*models[, for_concrete_models=True])
  154. Takes a variadic number of model classes, and returns a dictionary
  155. mapping the model classes to the
  156. :class:`~django.contrib.contenttypes.models.ContentType` instances
  157. representing them. ``for_concrete_models=False`` allows fetching the
  158. :class:`~django.contrib.contenttypes.models.ContentType` of proxy
  159. models.
  160. .. method:: get_by_natural_key(app_label, model)
  161. Returns the :class:`~django.contrib.contenttypes.models.ContentType`
  162. instance uniquely identified by the given application label and model
  163. name. The primary purpose of this method is to allow
  164. :class:`~django.contrib.contenttypes.models.ContentType` objects to be
  165. referenced via a :ref:`natural key<topics-serialization-natural-keys>`
  166. during deserialization.
  167. The :meth:`~ContentTypeManager.get_for_model()` method is especially
  168. useful when you know you need to work with a
  169. :class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't
  170. want to go to the trouble of obtaining the model's metadata to perform a manual
  171. lookup::
  172. >>> from django.contrib.auth.models import User
  173. >>> user_type = ContentType.objects.get_for_model(User)
  174. >>> user_type
  175. <ContentType: user>
  176. .. module:: django.contrib.contenttypes.fields
  177. .. _generic-relations:
  178. Generic relations
  179. =================
  180. Adding a foreign key from one of your own models to
  181. :class:`~django.contrib.contenttypes.models.ContentType` allows your model to
  182. effectively tie itself to another model class, as in the example of the
  183. :class:`~django.contrib.auth.models.Permission` model above. But it's possible
  184. to go one step further and use
  185. :class:`~django.contrib.contenttypes.models.ContentType` to enable truly
  186. generic (sometimes called "polymorphic") relationships between models.
  187. A simple example is a tagging system, which might look like this::
  188. from django.db import models
  189. from django.contrib.contenttypes.fields import GenericForeignKey
  190. from django.contrib.contenttypes.models import ContentType
  191. class TaggedItem(models.Model):
  192. tag = models.SlugField()
  193. content_type = models.ForeignKey(ContentType)
  194. object_id = models.PositiveIntegerField()
  195. content_object = GenericForeignKey('content_type', 'object_id')
  196. def __str__(self): # __unicode__ on Python 2
  197. return self.tag
  198. A normal :class:`~django.db.models.ForeignKey` can only "point
  199. to" one other model, which means that if the ``TaggedItem`` model used a
  200. :class:`~django.db.models.ForeignKey` it would have to
  201. choose one and only one model to store tags for. The contenttypes
  202. application provides a special field type (``GenericForeignKey``) which
  203. works around this and allows the relationship to be with any
  204. model:
  205. .. class:: GenericForeignKey
  206. There are three parts to setting up a
  207. :class:`~django.contrib.contenttypes.fields.GenericForeignKey`:
  208. 1. Give your model a :class:`~django.db.models.ForeignKey`
  209. to :class:`~django.contrib.contenttypes.models.ContentType`. The usual
  210. name for this field is "content_type".
  211. 2. Give your model a field that can store primary key values from the
  212. models you'll be relating to. For most models, this means a
  213. :class:`~django.db.models.PositiveIntegerField`. The usual name
  214. for this field is "object_id".
  215. 3. Give your model a
  216. :class:`~django.contrib.contenttypes.fields.GenericForeignKey`, and
  217. pass it the names of the two fields described above. If these fields
  218. are named "content_type" and "object_id", you can omit this -- those
  219. are the default field names
  220. :class:`~django.contrib.contenttypes.fields.GenericForeignKey` will
  221. look for.
  222. .. attribute:: GenericForeignKey.for_concrete_model
  223. If ``False``, the field will be able to reference proxy models. Default
  224. is ``True``. This mirrors the ``for_concrete_model`` argument to
  225. :meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`.
  226. .. versionchanged:: 1.7
  227. This class used to be defined in ``django.contrib.contenttypes.generic``.
  228. .. admonition:: Primary key type compatibility
  229. The "object_id" field doesn't have to be the same type as the
  230. primary key fields on the related models, but their primary key values
  231. must be coercible to the same type as the "object_id" field by its
  232. :meth:`~django.db.models.Field.get_db_prep_value` method.
  233. For example, if you want to allow generic relations to models with either
  234. :class:`~django.db.models.IntegerField` or
  235. :class:`~django.db.models.CharField` primary key fields, you
  236. can use :class:`~django.db.models.CharField` for the
  237. "object_id" field on your model since integers can be coerced to
  238. strings by :meth:`~django.db.models.Field.get_db_prep_value`.
  239. For maximum flexibility you can use a
  240. :class:`~django.db.models.TextField` which doesn't have a
  241. maximum length defined, however this may incur significant performance
  242. penalties depending on your database backend.
  243. There is no one-size-fits-all solution for which field type is best. You
  244. should evaluate the models you expect to be pointing to and determine
  245. which solution will be most effective for your use case.
  246. .. admonition:: Serializing references to ``ContentType`` objects
  247. If you're serializing data (for example, when generating
  248. :class:`~django.test.TransactionTestCase.fixtures`) from a model that implements
  249. generic relations, you should probably be using a natural key to uniquely
  250. identify related :class:`~django.contrib.contenttypes.models.ContentType`
  251. objects. See :ref:`natural keys<topics-serialization-natural-keys>` and
  252. :djadminopt:`dumpdata --natural <--natural>` for more information.
  253. This will enable an API similar to the one used for a normal
  254. :class:`~django.db.models.ForeignKey`;
  255. each ``TaggedItem`` will have a ``content_object`` field that returns the
  256. object it's related to, and you can also assign to that field or use it when
  257. creating a ``TaggedItem``::
  258. >>> from django.contrib.auth.models import User
  259. >>> guido = User.objects.get(username='Guido')
  260. >>> t = TaggedItem(content_object=guido, tag='bdfl')
  261. >>> t.save()
  262. >>> t.content_object
  263. <User: Guido>
  264. Due to the way :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
  265. is implemented, you cannot use such fields directly with filters (``filter()``
  266. and ``exclude()``, for example) via the database API. Because a
  267. :class:`~django.contrib.contenttypes.fields.GenericForeignKey` isn't a
  268. normal field object, these examples will *not* work::
  269. # This will fail
  270. >>> TaggedItem.objects.filter(content_object=guido)
  271. # This will also fail
  272. >>> TaggedItem.objects.get(content_object=guido)
  273. Likewise, :class:`~django.contrib.contenttypes.fields.GenericForeignKey`\s
  274. does not appear in :class:`~django.forms.ModelForm`\s.
  275. Reverse generic relations
  276. -------------------------
  277. .. class:: GenericRelation
  278. .. versionchanged:: 1.7
  279. This class used to be defined in ``django.contrib.contenttypes.generic``.
  280. .. attribute:: related_query_name
  281. .. versionadded:: 1.7
  282. The relation on the related object back to this object doesn't exist by
  283. default. Setting ``related_query_name`` creates a relation from the
  284. related object back to this one. This allows querying and filtering
  285. from the related object.
  286. If you know which models you'll be using most often, you can also add
  287. a "reverse" generic relationship to enable an additional API. For example::
  288. class Bookmark(models.Model):
  289. url = models.URLField()
  290. tags = GenericRelation(TaggedItem)
  291. ``Bookmark`` instances will each have a ``tags`` attribute, which can
  292. be used to retrieve their associated ``TaggedItems``::
  293. >>> b = Bookmark(url='https://www.djangoproject.com/')
  294. >>> b.save()
  295. >>> t1 = TaggedItem(content_object=b, tag='django')
  296. >>> t1.save()
  297. >>> t2 = TaggedItem(content_object=b, tag='python')
  298. >>> t2.save()
  299. >>> b.tags.all()
  300. [<TaggedItem: django>, <TaggedItem: python>]
  301. .. versionadded:: 1.7
  302. Defining :class:`~django.contrib.contenttypes.fields.GenericRelation` with
  303. ``related_query_name`` set allows querying from the related object::
  304. tags = GenericRelation(TaggedItem, related_query_name='bookmarks')
  305. This enables filtering, ordering, and other query operations on ``Bookmark``
  306. from ``TaggedItem``::
  307. >>> # Get all tags belonging to books containing `django` in the url
  308. >>> TaggedItem.objects.filter(bookmarks__url__contains='django')
  309. [<TaggedItem: django>, <TaggedItem: python>]
  310. Just as :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
  311. accepts the names of the content-type and object-ID fields as
  312. arguments, so too does
  313. :class:`~django.contrib.contenttypes.fields.GenericRelation`;
  314. if the model which has the generic foreign key is using non-default names
  315. for those fields, you must pass the names of the fields when setting up a
  316. :class:`.GenericRelation` to it. For example, if the ``TaggedItem`` model
  317. referred to above used fields named ``content_type_fk`` and
  318. ``object_primary_key`` to create its generic foreign key, then a
  319. :class:`.GenericRelation` back to it would need to be defined like so::
  320. tags = GenericRelation(TaggedItem,
  321. content_type_field='content_type_fk',
  322. object_id_field='object_primary_key')
  323. Of course, if you don't add the reverse relationship, you can do the
  324. same types of lookups manually::
  325. >>> b = Bookmark.objects.get(url='https://www.djangoproject.com/')
  326. >>> bookmark_type = ContentType.objects.get_for_model(b)
  327. >>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id,
  328. ... object_id=b.id)
  329. [<TaggedItem: django>, <TaggedItem: python>]
  330. Note that if the model in a
  331. :class:`~django.contrib.contenttypes.fields.GenericRelation` uses a
  332. non-default value for ``ct_field`` or ``fk_field`` in its
  333. :class:`~django.contrib.contenttypes.fields.GenericForeignKey` (for example, if
  334. you had a ``Comment`` model that uses ``ct_field="object_pk"``),
  335. you'll need to set ``content_type_field`` and/or ``object_id_field`` in
  336. the :class:`~django.contrib.contenttypes.fields.GenericRelation` to
  337. match the ``ct_field`` and ``fk_field``, respectively, in the
  338. :class:`~django.contrib.contenttypes.fields.GenericForeignKey`::
  339. comments = fields.GenericRelation(Comment, object_id_field="object_pk")
  340. Note also, that if you delete an object that has a
  341. :class:`~django.contrib.contenttypes.fields.GenericRelation`, any objects
  342. which have a :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
  343. pointing at it will be deleted as well. In the example above, this means that
  344. if a ``Bookmark`` object were deleted, any ``TaggedItem`` objects pointing at
  345. it would be deleted at the same time.
  346. Unlike :class:`~django.db.models.ForeignKey`,
  347. :class:`~django.contrib.contenttypes.fields.GenericForeignKey` does not accept
  348. an :attr:`~django.db.models.ForeignKey.on_delete` argument to customize this
  349. behavior; if desired, you can avoid the cascade-deletion simply by not using
  350. :class:`~django.contrib.contenttypes.fields.GenericRelation`, and alternate
  351. behavior can be provided via the :data:`~django.db.models.signals.pre_delete`
  352. signal.
  353. Generic relations and aggregation
  354. ---------------------------------
  355. :doc:`Django's database aggregation API </topics/db/aggregation>`
  356. doesn't work with a
  357. :class:`~django.contrib.contenttypes.fields.GenericRelation`. For example, you
  358. might be tempted to try something like::
  359. Bookmark.objects.aggregate(Count('tags'))
  360. This will not work correctly, however. The generic relation adds extra filters
  361. to the queryset to ensure the correct content type, but the
  362. :meth:`~django.db.models.query.QuerySet.aggregate` method doesn't take them
  363. into account. For now, if you need aggregates on generic relations, you'll
  364. need to calculate them without using the aggregation API.
  365. .. module:: django.contrib.contenttypes.forms
  366. Generic relation in forms
  367. -------------------------
  368. The :mod:`django.contrib.contenttypes.forms` module provides:
  369. * :class:`BaseGenericInlineFormSet`
  370. * A formset factory, :func:`generic_inlineformset_factory`, for use with
  371. :class:`~django.contrib.contenttypes.fields.GenericForeignKey`.
  372. .. class:: BaseGenericInlineFormSet
  373. .. versionchanged:: 1.7
  374. This class used to be defined in ``django.contrib.contenttypes.generic``.
  375. .. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True, min_num=None, validate_min=False)
  376. Returns a ``GenericInlineFormSet`` using
  377. :func:`~django.forms.models.modelformset_factory`.
  378. You must provide ``ct_field`` and ``fk_field`` if they are different from
  379. the defaults, ``content_type`` and ``object_id`` respectively. Other
  380. parameters are similar to those documented in
  381. :func:`~django.forms.models.modelformset_factory` and
  382. :func:`~django.forms.models.inlineformset_factory`.
  383. The ``for_concrete_model`` argument corresponds to the
  384. :class:`~django.contrib.contenttypes.fields.GenericForeignKey.for_concrete_model`
  385. argument on ``GenericForeignKey``.
  386. .. versionchanged:: 1.7
  387. This function used to be defined in ``django.contrib.contenttypes.generic``.
  388. .. versionchanged:: 1.7
  389. ``min_num`` and ``validate_min`` were added.
  390. .. module:: django.contrib.contenttypes.admin
  391. Generic relations in admin
  392. ------------------------------------
  393. The :mod:`django.contrib.contenttypes.admin` module provides
  394. :class:`~django.contrib.contenttypes.admin.GenericTabularInline` and
  395. :class:`~django.contrib.contenttypes.admin.GenericStackedInline` (subclasses of
  396. :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`)
  397. These classes and functions enable the use of generic relations in forms
  398. and the admin. See the :doc:`model formset </topics/forms/modelforms>` and
  399. :ref:`admin <using-generic-relations-as-an-inline>` documentation for more
  400. information.
  401. .. class:: GenericInlineModelAdmin
  402. The :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`
  403. class inherits all properties from an
  404. :class:`~django.contrib.admin.InlineModelAdmin` class. However,
  405. it adds a couple of its own for working with the generic relation:
  406. .. attribute:: ct_field
  407. The name of the
  408. :class:`~django.contrib.contenttypes.models.ContentType` foreign key
  409. field on the model. Defaults to ``content_type``.
  410. .. attribute:: ct_fk_field
  411. The name of the integer field that represents the ID of the related
  412. object. Defaults to ``object_id``.
  413. .. versionchanged:: 1.7
  414. This class used to be defined in ``django.contrib.contenttypes.generic``.
  415. .. class:: GenericTabularInline
  416. .. class:: GenericStackedInline
  417. Subclasses of :class:`GenericInlineModelAdmin` with stacked and tabular
  418. layouts, respectively.
  419. .. versionchanged:: 1.7
  420. These classes used to be defined in ``django.contrib.contenttypes.generic``.