<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The contenttypes framework — Django v1.1 documentation</title> <link rel="stylesheet" href="../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../', VERSION: '1.1', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <link rel="top" title="Django v1.1 documentation" href="../../index.html" /> <link rel="up" title="contrib packages" href="index.html" /> <link rel="next" title="Cross Site Request Forgery protection" href="csrf.html" /> <link rel="prev" title="Example of using the in-built comments app" href="comments/example.html" /> <script type="text/javascript" src="../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head> <body> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../index.html">Django v1.1 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../index.html">Home</a> | <a title="Table of contents" href="../../contents.html">Table of contents</a> | <a title="Global index" href="../../genindex.html">Index</a> | <a title="Module index" href="../../modindex.html">Modules</a> </div> <div class="nav"> « <a href="comments/example.html" title="Example of using the in-built comments app">previous</a> | <a href="../index.html" title="API Reference" accesskey="U">up</a> | <a href="csrf.html" title="Cross Site Request Forgery protection">next</a> »</div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="ref-contrib-contenttypes"> <div class="section" id="s-module-django.contrib.contenttypes"> <span id="s-ref-contrib-contenttypes"></span><span id="module-django.contrib.contenttypes"></span><span id="ref-contrib-contenttypes"></span><h1>The contenttypes framework<a class="headerlink" href="#module-django.contrib.contenttypes" title="Permalink to this headline">¶</a></h1> <p>Django includes a <tt class="xref docutils literal"><span class="pre">contenttypes</span></tt> application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models.</p> <div class="section" id="s-overview"> <span id="overview"></span><h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2> <p>At the heart of the contenttypes application is the <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> model, which lives at <tt class="docutils literal"><span class="pre">django.contrib.contenttypes.models.ContentType</span></tt>. Instances of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> represent and store information about the models installed in your project, and new instances of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> are automatically created whenever new models are installed.</p> <p>Instances of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> have methods for returning the model classes they represent and for querying objects from those models. <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> also has a <a class="reference external" href="../../topics/db/managers.html#custom-managers"><em>custom manager</em></a> that adds methods for working with <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> and for obtaining instances of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> for a particular model.</p> <p>Relations between your models and <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> can also be used to enable “generic” relationships between an instance of one of your models and instances of any model you have installed.</p> </div> <div class="section" id="s-installing-the-contenttypes-framework"> <span id="installing-the-contenttypes-framework"></span><h2>Installing the contenttypes framework<a class="headerlink" href="#installing-the-contenttypes-framework" title="Permalink to this headline">¶</a></h2> <p>The contenttypes framework is included in the default <a class="reference external" href="../settings.html#setting-INSTALLED_APPS"><tt class="xref docutils literal"><span class="pre">INSTALLED_APPS</span></tt></a> list created by <tt class="docutils literal"><span class="pre">django-admin.py</span> <span class="pre">startproject</span></tt>, but if you’ve removed it or if you manually set up your <a class="reference external" href="../settings.html#setting-INSTALLED_APPS"><tt class="xref docutils literal"><span class="pre">INSTALLED_APPS</span></tt></a> list, you can enable it by adding <tt class="docutils literal"><span class="pre">'django.contrib.contenttypes'</span></tt> to your <a class="reference external" href="../settings.html#setting-INSTALLED_APPS"><tt class="xref docutils literal"><span class="pre">INSTALLED_APPS</span></tt></a> setting.</p> <p>It’s generally a good idea to have the contenttypes framework installed; several of Django’s other bundled applications require it:</p> <ul class="simple"> <li>The admin application uses it to log the history of each object added or changed through the admin interface.</li> <li>Django’s <a title="Django's authentication framework." class="reference external" href="../../topics/auth.html#module-django.contrib.auth"><tt class="xref docutils literal"><span class="pre">authentication</span> <span class="pre">framework</span></tt></a> uses it to tie user permissions to specific models.</li> <li>Django’s comments system (<a title="Django's comment framework" class="reference external" href="comments/index.html#module-django.contrib.comments"><tt class="xref docutils literal"><span class="pre">django.contrib.comments</span></tt></a>) uses it to “attach” comments to any installed model.</li> </ul> </div> <div class="section" id="s-the-contenttype-model"> <span id="the-contenttype-model"></span><h2>The <tt class="docutils literal"><span class="pre">ContentType</span></tt> model<a class="headerlink" href="#the-contenttype-model" title="Permalink to this headline">¶</a></h2> <dl class="class"> <dt id="django.contrib.contenttypes.models.ContentType"> <em class="property">class </em><tt class="descclassname">models.</tt><tt class="descname">ContentType</tt><a class="headerlink" href="#django.contrib.contenttypes.models.ContentType" title="Permalink to this definition">¶</a></dt> <dd><p>Each instance of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> has three fields which, taken together, uniquely describe an installed model:</p> <dl class="attribute"> <dt id="django.contrib.contenttypes.models.ContentType.app_label"> <tt class="descname">app_label</tt><a class="headerlink" href="#django.contrib.contenttypes.models.ContentType.app_label" title="Permalink to this definition">¶</a></dt> <dd>The name of the application the model is part of. This is taken from the <a title="django.contrib.contenttypes.models.ContentType.app_label" class="reference internal" href="#django.contrib.contenttypes.models.ContentType.app_label"><tt class="xref docutils literal"><span class="pre">app_label</span></tt></a> attribute of the model, and includes only the <em>last</em> part of the application’s Python import path; “django.contrib.contenttypes”, for example, becomes an <a title="django.contrib.contenttypes.models.ContentType.app_label" class="reference internal" href="#django.contrib.contenttypes.models.ContentType.app_label"><tt class="xref docutils literal"><span class="pre">app_label</span></tt></a> of “contenttypes”.</dd></dl> <dl class="attribute"> <dt id="django.contrib.contenttypes.models.ContentType.model"> <tt class="descname">model</tt><a class="headerlink" href="#django.contrib.contenttypes.models.ContentType.model" title="Permalink to this definition">¶</a></dt> <dd>The name of the model class.</dd></dl> <dl class="attribute"> <dt id="django.contrib.contenttypes.models.ContentType.name"> <tt class="descname">name</tt><a class="headerlink" href="#django.contrib.contenttypes.models.ContentType.name" title="Permalink to this definition">¶</a></dt> <dd>The human-readable name of the model. This is taken from the <tt class="xref docutils literal"><span class="pre">verbose_name</span></tt> attribute of the model.</dd></dl> </dd></dl> <p>Let’s look at an example to see how this works. If you already have the contenttypes application installed, and then add <a title="Lets you operate multiple web sites from the same database and Django project" class="reference external" href="sites.html#module-django.contrib.sites"><tt class="xref docutils literal"><span class="pre">the</span> <span class="pre">sites</span> <span class="pre">application</span></tt></a> to your <a class="reference external" href="../settings.html#setting-INSTALLED_APPS"><tt class="xref docutils literal"><span class="pre">INSTALLED_APPS</span></tt></a> setting and run <tt class="docutils literal"><span class="pre">manage.py</span> <span class="pre">syncdb</span></tt> to install it, the model <tt class="xref docutils literal"><span class="pre">django.contrib.sites.models.Site</span></tt> will be installed into your database. Along with it a new instance of <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> will be created with the following values:</p> <ul class="simple"> <li><tt class="xref docutils literal"><span class="pre">app_label</span></tt> will be set to <tt class="docutils literal"><span class="pre">'sites'</span></tt> (the last part of the Python path “django.contrib.sites”).</li> <li><tt class="xref docutils literal"><span class="pre">model</span></tt> will be set to <tt class="docutils literal"><span class="pre">'site'</span></tt>.</li> <li><tt class="xref docutils literal"><span class="pre">name</span></tt> will be set to <tt class="docutils literal"><span class="pre">'site'</span></tt>.</li> </ul> </div> <div class="section" id="s-methods-on-contenttype-instances"> <span id="methods-on-contenttype-instances"></span><h2>Methods on <tt class="docutils literal"><span class="pre">ContentType</span></tt> instances<a class="headerlink" href="#methods-on-contenttype-instances" title="Permalink to this headline">¶</a></h2> <dl class="class"> <dt> <em class="property">class </em><tt class="descclassname">models.</tt><tt class="descname">ContentType</tt></dt> <dd>Each <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> instance has methods that allow you to get from a <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> instance to the model it represents, or to retrieve objects from that model:</dd></dl> <dl class="method"> <dt id="django.contrib.contenttypes.models.ContentType.get_object_for_this_type"> <tt class="descclassname">models.ContentType.</tt><tt class="descname">get_object_for_this_type</tt>(<em>**kwargs</em>)<a class="headerlink" href="#django.contrib.contenttypes.models.ContentType.get_object_for_this_type" title="Permalink to this definition">¶</a></dt> <dd>Takes a set of valid <a class="reference external" href="../../topics/db/queries.html#field-lookups-intro"><em>lookup arguments</em></a> for the model the <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> represents, and does <a class="reference external" href="../models/querysets.html#get-kwargs"><em>a get() lookup</em></a> on that model, returning the corresponding object.</dd></dl> <dl class="method"> <dt id="django.contrib.contenttypes.models.ContentType.model_class"> <tt class="descclassname">models.ContentType.</tt><tt class="descname">model_class</tt>()<a class="headerlink" href="#django.contrib.contenttypes.models.ContentType.model_class" title="Permalink to this definition">¶</a></dt> <dd>Returns the model class represented by this <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> instance.</dd></dl> <p>For example, we could look up the <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> for the <a title="django.contrib.auth.models.User" class="reference external" href="../../topics/auth.html#django.contrib.auth.models.User"><tt class="xref docutils literal"><span class="pre">User</span></tt></a> model:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span> <span class="gp">>>> </span><span class="n">user_type</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">app_label</span><span class="o">=</span><span class="s">"auth"</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="s">"user"</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">user_type</span> <span class="go"><ContentType: user></span> </pre></div> </div> <p>And then use it to query for a particular <tt class="docutils literal"><span class="pre">User</span></tt>, or to get access to the <tt class="docutils literal"><span class="pre">User</span></tt> model class:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">user_type</span><span class="o">.</span><span class="n">model_class</span><span class="p">()</span> <span class="go"><class 'django.contrib.auth.models.User'></span> <span class="gp">>>> </span><span class="n">user_type</span><span class="o">.</span><span class="n">get_object_for_this_type</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s">'Guido'</span><span class="p">)</span> <span class="go"><User: Guido></span> </pre></div> </div> <p>Together, <a title="django.contrib.contenttypes.models.ContentType.get_object_for_this_type" class="reference internal" href="#django.contrib.contenttypes.models.ContentType.get_object_for_this_type"><tt class="xref docutils literal"><span class="pre">get_object_for_this_type()</span></tt></a> and <a title="django.contrib.contenttypes.models.ContentType.model_class" class="reference internal" href="#django.contrib.contenttypes.models.ContentType.model_class"><tt class="xref docutils literal"><span class="pre">model_class()</span></tt></a> enable two extremely important use cases:</p> <ol class="arabic simple"> <li>Using these methods, you can write high-level generic code that performs queries on any installed model -- instead of importing and using a single specific model class, you can pass an <tt class="docutils literal"><span class="pre">app_label</span></tt> and <tt class="docutils literal"><span class="pre">model</span></tt> into a <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> lookup at runtime, and then work with the model class or retrieve objects from it.</li> <li>You can relate another model to <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> as a way of tying instances of it to particular model classes, and use these methods to get access to those model classes.</li> </ol> <p>Several of Django's bundled applications make use of the latter technique. For example, <a title="django.contrib.auth.models.Permission" class="reference external" href="../../topics/auth.html#django.contrib.auth.models.Permission"><tt class="xref docutils literal"><span class="pre">the</span> <span class="pre">permissions</span> <span class="pre">system</span> </tt></a> in Django's authentication framework uses a <a title="django.contrib.auth.models.Permission" class="reference external" href="../../topics/auth.html#django.contrib.auth.models.Permission"><tt class="xref docutils literal"><span class="pre">Permission</span></tt></a> model with a foreign key to <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a>; this lets <a title="django.contrib.auth.models.Permission" class="reference external" href="../../topics/auth.html#django.contrib.auth.models.Permission"><tt class="xref docutils literal"><span class="pre">Permission</span></tt></a> represent concepts like "can add blog entry" or "can delete news story".</p> <div class="section" id="s-the-contenttypemanager"> <span id="the-contenttypemanager"></span><h3>The <tt class="docutils literal"><span class="pre">ContentTypeManager</span></tt><a class="headerlink" href="#the-contenttypemanager" title="Permalink to this headline">¶</a></h3> <dl class="class"> <dt id="django.contrib.contenttypes.models.ContentTypeManager"> <em class="property">class </em><tt class="descclassname">models.</tt><tt class="descname">ContentTypeManager</tt><a class="headerlink" href="#django.contrib.contenttypes.models.ContentTypeManager" title="Permalink to this definition">¶</a></dt> <dd><p><a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> also has a custom manager, <a title="django.contrib.contenttypes.models.ContentTypeManager" class="reference internal" href="#django.contrib.contenttypes.models.ContentTypeManager"><tt class="xref docutils literal"><span class="pre">ContentTypeManager</span></tt></a>, which adds the following methods:</p> <dl class="method"> <dt id="django.contrib.contenttypes.models.ContentTypeManager.clear_cache"> <tt class="descname">clear_cache</tt>()<a class="headerlink" href="#django.contrib.contenttypes.models.ContentTypeManager.clear_cache" title="Permalink to this definition">¶</a></dt> <dd>Clears an internal cache used by <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> to keep track of which models for which it has created <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">django.contrib.contenttypes.models.ContentType</span></tt></a> instances. You probably won't ever need to call this method yourself; Django will call it automatically when it's needed.</dd></dl> <dl class="method"> <dt id="django.contrib.contenttypes.models.ContentTypeManager.get_for_model"> <tt class="descname">get_for_model</tt>(<em>model</em>)<a class="headerlink" href="#django.contrib.contenttypes.models.ContentTypeManager.get_for_model" title="Permalink to this definition">¶</a></dt> <dd>Takes either a model class or an instance of a model, and returns the <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> instance representing that model.</dd></dl> </dd></dl> <p>The <a title="django.contrib.contenttypes.models.ContentTypeManager.get_for_model" class="reference internal" href="#django.contrib.contenttypes.models.ContentTypeManager.get_for_model"><tt class="xref docutils literal"><span class="pre">get_for_model()</span></tt></a> method is especially useful when you know you need to work with a <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> but don't want to go to the trouble of obtaining the model's metadata to perform a manual lookup:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span> <span class="gp">>>> </span><span class="n">user_type</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_for_model</span><span class="p">(</span><span class="n">User</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">user_type</span> <span class="go"><ContentType: user></span> </pre></div> </div> </div> </div> <div class="section" id="s-generic-relations"> <span id="s-id1"></span><span id="generic-relations"></span><span id="id1"></span><h2>Generic relations<a class="headerlink" href="#generic-relations" title="Permalink to this headline">¶</a></h2> <p>Adding a foreign key from one of your own models to <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> allows your model to effectively tie itself to another model class, as in the example of the <a title="django.contrib.auth.models.Permission" class="reference external" href="../../topics/auth.html#django.contrib.auth.models.Permission"><tt class="xref docutils literal"><span class="pre">Permission</span></tt></a> model above. But it's possible to go one step further and use <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> to enable truly generic (sometimes called "polymorphic") relationships between models.</p> <p>A simple example is a tagging system, which might look like this:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span> <span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span> <span class="kn">from</span> <span class="nn">django.contrib.contenttypes</span> <span class="kn">import</span> <span class="n">generic</span> <span class="k">class</span> <span class="nc">TaggedItem</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span> <span class="n">tag</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">SlugField</span><span class="p">()</span> <span class="n">content_type</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">ContentType</span><span class="p">)</span> <span class="n">object_id</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">PositiveIntegerField</span><span class="p">()</span> <span class="n">content_object</span> <span class="o">=</span> <span class="n">generic</span><span class="o">.</span><span class="n">GenericForeignKey</span><span class="p">(</span><span class="s">'content_type'</span><span class="p">,</span> <span class="s">'object_id'</span><span class="p">)</span> <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tag</span> </pre></div> </div> <p>A normal <tt class="xref docutils literal"><span class="pre">ForeignKey</span></tt> can only "point to" one other model, which means that if the <tt class="docutils literal"><span class="pre">TaggedItem</span></tt> model used a <tt class="xref docutils literal"><span class="pre">ForeignKey</span></tt> it would have to choose one and only one model to store tags for. The contenttypes application provides a special field type -- <tt class="xref docutils literal"><span class="pre">django.contrib.contenttypes.generic.GenericForeignKey</span></tt> -- which works around this and allows the relationship to be with any model. There are three parts to setting up a <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt>:</p> <ol class="arabic"> <li><p class="first">Give your model a <tt class="xref docutils literal"><span class="pre">ForeignKey</span></tt> to <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a>.</p> </li> <li><p class="first">Give your model a field that can store a primary-key value from the models you'll be relating to. (For most models, this means an <tt class="xref docutils literal"><span class="pre">IntegerField</span></tt> or <tt class="xref docutils literal"><span class="pre">PositiveIntegerField</span></tt>.)</p> <p>This field must be of the same type as the primary key of the models that will be involved in the generic relation. For example, if you use <tt class="xref docutils literal"><span class="pre">IntegerField</span></tt>, you won't be able to form a generic relation with a model that uses a <tt class="xref docutils literal"><span class="pre">CharField</span></tt> as a primary key.</p> </li> <li><p class="first">Give your model a <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt>, and pass it the names of the two fields described above. If these fields are named "content_type" and "object_id", you can omit this -- those are the default field names <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt> will look for.</p> </li> </ol> <p>This will enable an API similar to the one used for a normal <tt class="xref docutils literal"><span class="pre">ForeignKey</span></tt>; each <tt class="docutils literal"><span class="pre">TaggedItem</span></tt> will have a <tt class="docutils literal"><span class="pre">content_object</span></tt> field that returns the object it's related to, and you can also assign to that field or use it when creating a <tt class="docutils literal"><span class="pre">TaggedItem</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span> <span class="gp">>>> </span><span class="n">guido</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s">'Guido'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">t</span> <span class="o">=</span> <span class="n">TaggedItem</span><span class="p">(</span><span class="n">content_object</span><span class="o">=</span><span class="n">guido</span><span class="p">,</span> <span class="n">tag</span><span class="o">=</span><span class="s">'bdfl'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">t</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="gp">>>> </span><span class="n">t</span><span class="o">.</span><span class="n">content_object</span> <span class="go"><User: Guido></span> </pre></div> </div> <p>Due to the way <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt> is implemented, you cannot use such fields directly with filters (<tt class="docutils literal"><span class="pre">filter()</span></tt> and <tt class="docutils literal"><span class="pre">exclude()</span></tt>, for example) via the database API. They aren't normal field objects. These examples will <em>not</em> work:</p> <div class="highlight-python"><pre># This will fail >>> TaggedItem.objects.filter(content_object=guido) # This will also fail >>> TaggedItem.objects.get(content_object=guido)</pre> </div> <div class="section" id="s-reverse-generic-relations"> <span id="reverse-generic-relations"></span><h3>Reverse generic relations<a class="headerlink" href="#reverse-generic-relations" title="Permalink to this headline">¶</a></h3> <p>If you know which models you'll be using most often, you can also add a "reverse" generic relationship to enable an additional API. For example:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span> <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">()</span> <span class="n">tags</span> <span class="o">=</span> <span class="n">generic</span><span class="o">.</span><span class="n">GenericRelation</span><span class="p">(</span><span class="n">TaggedItem</span><span class="p">)</span> </pre></div> </div> <p><tt class="docutils literal"><span class="pre">Bookmark</span></tt> instances will each have a <tt class="docutils literal"><span class="pre">tags</span></tt> attribute, which can be used to retrieve their associated <tt class="docutils literal"><span class="pre">TaggedItems</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">b</span> <span class="o">=</span> <span class="n">Bookmark</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">'http://www.djangoproject.com/'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">b</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="gp">>>> </span><span class="n">t1</span> <span class="o">=</span> <span class="n">TaggedItem</span><span class="p">(</span><span class="n">content_object</span><span class="o">=</span><span class="n">b</span><span class="p">,</span> <span class="n">tag</span><span class="o">=</span><span class="s">'django'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">t1</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="gp">>>> </span><span class="n">t2</span> <span class="o">=</span> <span class="n">TaggedItem</span><span class="p">(</span><span class="n">content_object</span><span class="o">=</span><span class="n">b</span><span class="p">,</span> <span class="n">tag</span><span class="o">=</span><span class="s">'python'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">t2</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="gp">>>> </span><span class="n">b</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="go">[<TaggedItem: django>, <TaggedItem: python>]</span> </pre></div> </div> <p>Just as <tt class="xref docutils literal"><span class="pre">django.contrib.contenttypes.generic.GenericForeignKey</span></tt> accepts the names of the content-type and object-ID fields as arguments, so too does <tt class="docutils literal"><span class="pre">GenericRelation</span></tt>; if the model which has the generic foreign key is using non-default names for those fields, you must pass the names of the fields when setting up a <tt class="docutils literal"><span class="pre">GenericRelation</span></tt> to it. For example, if the <tt class="docutils literal"><span class="pre">TaggedItem</span></tt> model referred to above used fields named <tt class="docutils literal"><span class="pre">content_type_fk</span></tt> and <tt class="docutils literal"><span class="pre">object_primary_key</span></tt> to create its generic foreign key, then a <tt class="docutils literal"><span class="pre">GenericRelation</span></tt> back to it would need to be defined like so:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">tags</span> <span class="o">=</span> <span class="n">generic</span><span class="o">.</span><span class="n">GenericRelation</span><span class="p">(</span><span class="n">TaggedItem</span><span class="p">,</span> <span class="n">content_type_field</span><span class="o">=</span><span class="s">'content_type_fk'</span><span class="p">,</span> <span class="n">object_id_field</span><span class="o">=</span><span class="s">'object_primary_key'</span><span class="p">)</span> </pre></div> </div> <p>Of course, if you don't add the reverse relationship, you can do the same types of lookups manually:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">b</span> <span class="o">=</span> <span class="n">Bookmark</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">'http://www.djangoproject.com/'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">bookmark_type</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_for_model</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">TaggedItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">content_type__pk</span><span class="o">=</span><span class="n">bookmark_type</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="gp">... </span> <span class="n">object_id</span><span class="o">=</span><span class="n">b</span><span class="o">.</span><span class="n">id</span><span class="p">)</span> <span class="go">[<TaggedItem: django>, <TaggedItem: python>]</span> </pre></div> </div> <p>Note that if the model with a <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt> that you're referring to uses a non-default value for <tt class="docutils literal"><span class="pre">ct_field</span></tt> or <tt class="docutils literal"><span class="pre">fk_field</span></tt> (e.g. the <a title="Django's comment framework" class="reference external" href="comments/index.html#module-django.contrib.comments"><tt class="xref docutils literal"><span class="pre">django.contrib.comments</span></tt></a> app uses <tt class="docutils literal"><span class="pre">ct_field="object_pk"</span></tt>), you'll need to pass <tt class="docutils literal"><span class="pre">content_type_field</span></tt> and <tt class="docutils literal"><span class="pre">object_id_field</span></tt> to <tt class="xref docutils literal"><span class="pre">GenericRelation</span></tt>.:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">comments</span> <span class="o">=</span> <span class="n">generic</span><span class="o">.</span><span class="n">GenericRelation</span><span class="p">(</span><span class="n">Comment</span><span class="p">,</span> <span class="n">content_type_field</span><span class="o">=</span><span class="s">"content_type"</span><span class="p">,</span> <span class="n">object_id_field</span><span class="o">=</span><span class="s">"object_pk"</span><span class="p">)</span> </pre></div> </div> <p>Note that if you delete an object that has a <tt class="xref docutils literal"><span class="pre">GenericRelation</span></tt>, any objects which have a <tt class="xref docutils literal"><span class="pre">GenericForeignKey</span></tt> pointing at it will be deleted as well. In the example above, this means that if a <tt class="docutils literal"><span class="pre">Bookmark</span></tt> object were deleted, any <tt class="docutils literal"><span class="pre">TaggedItem</span></tt> objects pointing at it would be deleted at the same time.</p> </div> <div class="section" id="s-generic-relations-and-aggregation"> <span id="generic-relations-and-aggregation"></span><h3>Generic relations and aggregation<a class="headerlink" href="#generic-relations-and-aggregation" title="Permalink to this headline">¶</a></h3> <p><a class="reference external" href="../../topics/db/aggregation.html#topics-db-aggregation"><em>Django's database aggregation API </em></a> doesn't work with a <tt class="xref docutils literal"><span class="pre">GenericRelation</span></tt>. For example, you might be tempted to try something like:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">Bookmark</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">Count</span><span class="p">(</span><span class="s">'tags'</span><span class="p">))</span> </pre></div> </div> <p>This will not work correctly, however. The generic relation adds extra filters to the queryset to ensure the correct content type, but the <tt class="docutils literal"><span class="pre">aggregate</span></tt> method doesn't take them into account. For now, if you need aggregates on generic relations, you'll need to calculate them without using the aggregation API.</p> </div> <div class="section" id="s-generic-relations-in-forms-and-admin"> <span id="generic-relations-in-forms-and-admin"></span><h3>Generic relations in forms and admin<a class="headerlink" href="#generic-relations-in-forms-and-admin" title="Permalink to this headline">¶</a></h3> <p><tt class="xref docutils literal"><span class="pre">django.contrib.contenttypes.generic</span></tt> provides both a <tt class="xref docutils literal"><span class="pre">GenericInlineFormSet</span></tt> and <a title="django.contrib.contenttypes.generic.GenericInlineModelAdmin" class="reference internal" href="#django.contrib.contenttypes.generic.GenericInlineModelAdmin"><tt class="xref docutils literal"><span class="pre">GenericInlineModelAdmin</span></tt></a>. This enables the use of generic relations in forms and the admin. See the <a class="reference external" href="../../topics/forms/modelforms.html#topics-forms-modelforms"><em>model formset</em></a> and <a class="reference external" href="admin/index.html#ref-contrib-admin"><em>admin</em></a> documentation for more information.</p> <dl class="class"> <dt id="django.contrib.contenttypes.generic.GenericInlineModelAdmin"> <em class="property">class </em><tt class="descclassname">generic.</tt><tt class="descname">GenericInlineModelAdmin</tt><a class="headerlink" href="#django.contrib.contenttypes.generic.GenericInlineModelAdmin" title="Permalink to this definition">¶</a></dt> <dd><p>The <a title="django.contrib.contenttypes.generic.GenericInlineModelAdmin" class="reference internal" href="#django.contrib.contenttypes.generic.GenericInlineModelAdmin"><tt class="xref docutils literal"><span class="pre">GenericInlineModelAdmin</span></tt></a> class inherits all properties from an <tt class="xref docutils literal"><span class="pre">InlineModelAdmin</span></tt> class. However, it adds a couple of its own for working with the generic relation:</p> <dl class="attribute"> <dt id="django.contrib.contenttypes.generic.GenericInlineModelAdmin.ct_field"> <tt class="descname">ct_field</tt><a class="headerlink" href="#django.contrib.contenttypes.generic.GenericInlineModelAdmin.ct_field" title="Permalink to this definition">¶</a></dt> <dd>The name of the <a title="django.contrib.contenttypes.models.ContentType" class="reference internal" href="#django.contrib.contenttypes.models.ContentType"><tt class="xref docutils literal"><span class="pre">ContentType</span></tt></a> foreign key field on the model. Defaults to <tt class="docutils literal"><span class="pre">content_type</span></tt>.</dd></dl> <dl class="attribute"> <dt id="django.contrib.contenttypes.generic.GenericInlineModelAdmin.ct_fk_field"> <tt class="descname">ct_fk_field</tt><a class="headerlink" href="#django.contrib.contenttypes.generic.GenericInlineModelAdmin.ct_fk_field" title="Permalink to this definition">¶</a></dt> <dd>The name of the integer field that represents the ID of the related object. Defaults to <tt class="docutils literal"><span class="pre">object_id</span></tt>.</dd></dl> </dd></dl> </div> </div> </div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference external" href="#">The contenttypes framework</a><ul> <li><a class="reference external" href="#overview">Overview</a></li> <li><a class="reference external" href="#installing-the-contenttypes-framework">Installing the contenttypes framework</a></li> <li><a class="reference external" href="#the-contenttype-model">The <tt class="docutils literal"><span class="pre">ContentType</span></tt> model</a></li> <li><a class="reference external" href="#methods-on-contenttype-instances">Methods on <tt class="docutils literal"><span class="pre">ContentType</span></tt> instances</a><ul> <li><a class="reference external" href="#the-contenttypemanager">The <tt class="docutils literal"><span class="pre">ContentTypeManager</span></tt></a></li> </ul> </li> <li><a class="reference external" href="#generic-relations">Generic relations</a><ul> <li><a class="reference external" href="#reverse-generic-relations">Reverse generic relations</a></li> <li><a class="reference external" href="#generic-relations-and-aggregation">Generic relations and aggregation</a></li> <li><a class="reference external" href="#generic-relations-in-forms-and-admin">Generic relations in forms and admin</a></li> </ul> </li> </ul> </li> </ul> <h3>Browse</h3> <ul> <li>Prev: <a href="comments/example.html">Example of using the in-built comments app</a></li> <li>Next: <a href="csrf.html">Cross Site Request Forgery protection</a></li> </ul> <h3>You are here:</h3> <ul> <li> <a href="../../index.html">Django v1.1 documentation</a> <ul><li><a href="../index.html">API Reference</a> <ul><li><a href="index.html"><tt class="docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal"><span class="pre">contrib</span></tt> packages</a> <ul><li>The contenttypes framework</li></ul> </li></ul></li></ul> </li> </ul> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../../_sources/ref/contrib/contenttypes.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">Feb 18, 2011</p> </div> </div> <div id="ft"> <div class="nav"> « <a href="comments/example.html" title="Example of using the in-built comments app">previous</a> | <a href="../index.html" title="API Reference" accesskey="U">up</a> | <a href="csrf.html" title="Cross Site Request Forgery protection">next</a> »</div> </div> </div> <div class="clearer"></div> </div> </body> </html>