Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 41d7a6f918
Fetching contributors…

Cannot retrieve contributors at this time

1024 lines (963 sloc) 88.19 kb
<!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>Chapter 3. Building a Pastebin. &mdash; Djen of Django</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Djen of Django" href="index.html" />
<link rel="next" title="Chapter 4. Building a Blog" href="chapter4.html" />
<link rel="prev" title="Chapter 2. Building a personal CD library." href="chapter2.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="chapter4.html" title="Chapter 4. Building a Blog"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="chapter2.html" title="Chapter 2. Building a personal CD library."
accesskey="P">previous</a> |</li>
<li><a href="index.html">Djen of Django</a> &raquo;</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Chapter 3. Building a Pastebin.</a><ul>
<li><a class="reference internal" href="#url-configuration-entry-points">URL configuration - entry points:</a><ul>
<li><a class="reference internal" href="#named-urls">Named urls:</a></li>
<li><a class="reference internal" href="#grouped-urls">Grouped urls:</a></li>
</ul>
</li>
<li><a class="reference internal" href="#templates-skeletons-of-our-website">Templates - skeletons of our website:</a><ul>
<li><a class="reference internal" href="#template-loaders">Template Loaders:</a></li>
<li><a class="reference internal" href="#context">Context:</a></li>
<li><a class="reference internal" href="#templatetags">Templatetags:</a></li>
<li><a class="reference internal" href="#common-templatetags-and-template-inheritance">Common templatetags and template inheritance:</a></li>
<li><a class="reference internal" href="#filters">Filters:</a></li>
<li><a class="reference internal" href="#templates-are-not-meant-for-programming">Templates are not meant for programming:</a></li>
</ul>
</li>
<li><a class="reference internal" href="#generic-views-commonly-used-views">Generic views - commonly used views:</a><ul>
<li><a class="reference internal" href="#views">Views:</a></li>
<li><a class="reference internal" href="#generic-views">Generic Views:</a></li>
<li><a class="reference internal" href="#create-update-create-object"><tt class="docutils literal"><span class="pre">create_update.create_object</span></tt></a></li>
<li><a class="reference internal" href="#create-update-update-object"><tt class="docutils literal"><span class="pre">create_update.update_object</span></tt></a></li>
<li><a class="reference internal" href="#create-update-delete-object"><tt class="docutils literal"><span class="pre">create_update.delete_object</span></tt></a></li>
<li><a class="reference internal" href="#list-detail-object-list"><tt class="docutils literal"><span class="pre">list_detail.object_list</span></tt></a></li>
<li><a class="reference internal" href="#list-detail-object-detail"><tt class="docutils literal"><span class="pre">list_detail.object_detail</span></tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#designing-a-pastebin-app">Designing a pastebin app:</a></li>
<li><a class="reference internal" href="#sketch-the-models">Sketch the models:</a></li>
<li><a class="reference internal" href="#configuring-urls">Configuring urls:</a></li>
<li><a class="reference internal" href="#writing-custom-management-scripts">Writing custom management scripts:</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="chapter2.html"
title="previous chapter">Chapter 2. Building a personal CD library.</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="chapter4.html"
title="next chapter">Chapter 4. Building a Blog</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/chapter3.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>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="chapter-3-building-a-pastebin">
<h1>Chapter 3. Building a Pastebin.<a class="headerlink" href="#chapter-3-building-a-pastebin" title="Permalink to this headline">¶</a></h1>
<div class="section" id="url-configuration-entry-points">
<h2>URL configuration - entry points:<a class="headerlink" href="#url-configuration-entry-points" title="Permalink to this headline">¶</a></h2>
<p>We have already noticed urls.py in our project. This controls our website&#8217;s
points of entry. All incoming urls will be matched with the regexes in the
<tt class="docutils literal"><span class="pre">urlpatterns</span></tt> and the view corresponding to the first match will get to handle
the request. A request url that does not match any urlconf entry will be 404&#8217;ed.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">brush up regexes in python from <a class="reference external" href="http://docs.python.org/library/re.html">python docs</a> or
<a class="reference external" href="http://diveintopython.org/regular_expressions/index.html">diveintopython</a></p>
</div>
<p>As an example from our previous app:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="c"># Uncomment the next two lines to enable the admin:</span>
<span class="kn">from</span> <span class="nn">django.contrib</span> <span class="kn">import</span> <span class="n">admin</span>
<span class="n">admin</span><span class="o">.</span><span class="n">autodiscover</span><span class="p">()</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="c"># Example:</span>
<span class="c"># (r&#39;^djen_project/&#39;, include(&#39;djen_project.foo.urls&#39;)),</span>
<span class="c"># Uncomment the admin/doc line below and add &#39;django.contrib.admindocs&#39; </span>
<span class="c"># to INSTALLED_APPS to enable admin documentation:</span>
<span class="c"># (r&#39;^admin/doc/&#39;, include(&#39;django.contrib.admindocs.urls&#39;)),</span>
<span class="c"># Uncomment the next line to enable the admin:</span>
<span class="p">(</span><span class="s">r&#39;^accounts/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;registration.backends.default.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^admin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">urls</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^pastebin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;pastebin.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^blog/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;blog.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^wiki/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;wiki.urls&#39;</span><span class="p">)),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Now when we call <a class="reference external" href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a> django matches that to the first regex. This urlconf
has included <tt class="docutils literal"><span class="pre">admin.urls</span></tt> which means that all further regex matches will be done with the <tt class="docutils literal"><span class="pre">admin.urls</span></tt>
module. Once again, the first match will get to handle the request. You can think of this as &#8216;mounting&#8217; the
admin app at <tt class="docutils literal"><span class="pre">/admin/</span></tt>. You are of course free to change the &#8216;mount point&#8217; to anything else you like.</p>
<p>A typical urlconf entry looks like this:</p>
<div class="highlight-python"><pre>(r'&lt;regex&gt;', &lt;view_function&gt;, &lt;arg_dict&gt;),</pre>
</div>
<p><tt class="docutils literal"><span class="pre">regex</span></tt> is any valid python regex that has to be processed. This would be absolute in the project
urls.py and relative to the mount point in an app&#8217;s urls.py</p>
<p><tt class="docutils literal"><span class="pre">view_function</span></tt> is a function that corresponds to this url. The function <strong>must</strong> return a <tt class="docutils literal"><span class="pre">HttpResponse</span></tt>
object. Usually, shortcuts such as <tt class="docutils literal"><span class="pre">render_to_response</span></tt>, are used though. More about views later.</p>
<p><tt class="docutils literal"><span class="pre">arg_dict</span></tt> is an optional dict of arguments that will be passed to the <tt class="docutils literal"><span class="pre">view_function</span></tt>. In addition, options
can be declared from the url regex too. For example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">(</span><span class="s">r&#39;^object/?P&lt;object_id&gt;(\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;objects.views.get_object&#39;</span><span class="p">),</span>
</pre></div>
</div>
<p>will match all urls having an integer after <tt class="docutils literal"><span class="pre">object/</span></tt>. Also, the value will be passed as <tt class="docutils literal"><span class="pre">object_id</span></tt> to the
<tt class="docutils literal"><span class="pre">get_object</span></tt> function.</p>
<div class="section" id="named-urls">
<h3>Named urls:<a class="headerlink" href="#named-urls" title="Permalink to this headline">¶</a></h3>
<p>Usually, we would want an easier way to remember the urls so that we could refer them in views or templates.
We could <em>name</em> our urls by using the <tt class="docutils literal"><span class="pre">url</span></tt> constructor. For example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">url</span><span class="p">(</span><span class="s">r&#39;^welcome/$&#39;</span><span class="p">,</span> <span class="s">&#39;app.views.welcome&#39;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;welcome&#39;</span><span class="p">),</span>
</pre></div>
</div>
<p>This line is similar to the previous urls, but we have an option of passing a <tt class="docutils literal"><span class="pre">name</span></tt> argument.</p>
<p>To get back the url from its name, django provides:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">django.core.urlresolvers.reverse</span></tt> function for use in views</li>
<li><tt class="docutils literal"><span class="pre">url</span></tt> templatetag for use in templates</li>
</ul>
<p>We will see how to use the templatetag in our templates.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Also see <a class="reference external" href="http://agiliq.com/books/djangodesignpatterns/urls.html#naming-urls">http://agiliq.com/books/djangodesignpatterns/urls.html#naming-urls</a></p>
</div>
</div>
<div class="section" id="grouped-urls">
<h3>Grouped urls:<a class="headerlink" href="#grouped-urls" title="Permalink to this headline">¶</a></h3>
<p>Sometimes, we would want to group together logically related urls. Or just avoid writing the full function path
over and over. We can do this by putting the common path to the view function in the first argument of
urlpatterns:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">}),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>and:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;django.views.generic.create_update&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="s">&#39;create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">}),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>are equivalent.</p>
</div>
</div>
<div class="section" id="templates-skeletons-of-our-website">
<h2>Templates - skeletons of our website:<a class="headerlink" href="#templates-skeletons-of-our-website" title="Permalink to this headline">¶</a></h2>
<p>You must be wondering where all those pages came from, since we have not touched
any html yet. Well, since we used the admin app, we were able to rely on the admin
templates supplied with django.</p>
<p>A template is a structure of webpage that will be <em>rendered</em> using a <em>context</em> and returned as response if
you want it to. A <tt class="docutils literal"><span class="pre">django.template.Template</span></tt> object can be rendered using the <tt class="docutils literal"><span class="pre">render</span></tt> method.</p>
<p>Normally templates are html files with some extra django content, such as templatetags and variables. Note that our
templates need to be publicly accessible(in fact they shouldn&#8217;t be) from a webserver. They are not meant to be displayed
directly, django will process them based on the request, context etc and respond with the rendered templates.</p>
<p>In case you want a template to be directly accessible (e.g. static html files), you could use the <tt class="docutils literal"><span class="pre">django.views.generic.simple.direct_to_template</span></tt>
generic view.</p>
<div class="section" id="template-loaders">
<h3>Template Loaders:<a class="headerlink" href="#template-loaders" title="Permalink to this headline">¶</a></h3>
<p>Django will usually look for templates in <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt> of settings.py and inside <tt class="docutils literal"><span class="pre">templates</span></tt> directory of each app.
This is because of the <tt class="docutils literal"><span class="pre">TEMPLATE_LOADERS</span></tt> in the default settings.py:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># List of callables that know how to import templates from various sources.</span>
<span class="n">TEMPLATE_LOADERS</span> <span class="o">=</span> <span class="p">(</span>
<span class="s">&#39;django.template.loaders.filesystem.Loader&#39;</span><span class="p">,</span>
<span class="s">&#39;django.template.loaders.app_directories.Loader&#39;</span><span class="p">,</span>
<span class="c"># &#39;django.template.loaders.eggs.Loader&#39;,</span>
<span class="p">)</span>
</pre></div>
</div>
<p>These functions fetch the template based on a given template path. To let django locate your <tt class="docutils literal"><span class="pre">hello_world.html</span></tt>
you would have to place it in <tt class="docutils literal"><span class="pre">&lt;app&gt;/templates</span></tt> or place it in any directory and set the <tt class="docutils literal"><span class="pre">TEMPLATE_DIRS</span></tt>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">TEMPLATE_DIRS</span> <span class="o">=</span> <span class="p">(</span>
<span class="c"># Put strings here, like &quot;/home/html/django_templates&quot; or &quot;C:/www/django/templates&quot;.</span>
<span class="c"># Always use forward slashes, even on Windows.</span>
<span class="c"># Don&#39;t forget to use absolute paths, not relative paths.</span>
<span class="p">)</span>
</pre></div>
</div>
<p>to the absolute path of that directory.</p>
</div>
<div class="section" id="context">
<h3>Context:<a class="headerlink" href="#context" title="Permalink to this headline">¶</a></h3>
<p>A context is a dict that will be used to render a page from a template. All context keys are valid template
variables.</p>
<p>To display a user name in your template, suppose you provide the <tt class="docutils literal"><span class="pre">username</span></tt> in your context, you could do:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">Hello </span><span class="cp">{{</span> <span class="nv">username</span> <span class="cp">}}</span><span class="x"></span>
</pre></div>
</div>
<p>When this template is rendered using (e.g. using <tt class="docutils literal"><span class="pre">render_to_response</span></tt>), <tt class="docutils literal"><span class="pre">username</span></tt> will be replaced with its value</p>
<p>You can pass any variable to the context, so you can call a dict&#8217;s key, or an objects property. However you cannot pass
any arguments to the property.</p>
<p>For example:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">Hello </span><span class="cp">{{</span> <span class="nv">user.username</span> <span class="cp">}}</span><span class="x"></span>
</pre></div>
</div>
<p>can be used to get <tt class="docutils literal"><span class="pre">user['username']</span></tt> or <tt class="docutils literal"><span class="pre">user.username</span></tt></p>
<p>Similarly:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;a hef=&quot;</span><span class="cp">{{</span> <span class="nv">user.get_absolute_url</span> <span class="cp">}}</span><span class="x">&quot;&gt;</span><span class="cp">{{</span> <span class="nv">user.username</span> <span class="cp">}}</span><span class="x">&lt;/a&gt;</span>
</pre></div>
</div>
<p>can be used to get <tt class="docutils literal"><span class="pre">user.get_absolute_url()</span></tt></p>
</div>
<div class="section" id="templatetags">
<h3>Templatetags:<a class="headerlink" href="#templatetags" title="Permalink to this headline">¶</a></h3>
<p>Templatetags are helpers to the template. Suppose you have an <tt class="docutils literal"><span class="pre">iterable</span></tt> with a list of objects in your context:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">for</span> <span class="nv">object</span> <span class="k">in</span> <span class="nv">objects</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">object</span> <span class="cp">}}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
</div>
<p>would render them. If this is a html template, we would prefer:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">objects</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">object</span> <span class="k">in</span> <span class="nv">objects</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">object</span> <span class="cp">}}</span><span class="x"></span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;/ul&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
</div>
<p>which would render the objects in html unordered list.</p>
<p>Note that <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">if</span> <span class="pre">%}</span></tt> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">%}</span></tt> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">endif</span> <span class="pre">%}</span></tt> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">endfor</span> <span class="pre">%}</span></tt> are all built-in templatetags.
If and for behave very much like their python counterparts.</p>
</div>
<div class="section" id="common-templatetags-and-template-inheritance">
<h3>Common templatetags and template inheritance:<a class="headerlink" href="#common-templatetags-and-template-inheritance" title="Permalink to this headline">¶</a></h3>
<p>Some templatetags we will use in our application:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">url</span></tt></li>
</ul>
<p>This templatetag takes a named url or view function and renders the url as found by <tt class="docutils literal"><span class="pre">reverse</span></tt></p>
<blockquote>
For example:</blockquote>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_list</span> <span class="cp">%}</span><span class="x">&quot;&gt;View All&lt;/a&gt;</span>
</pre></div>
</div>
<p>would output</p>
<div class="highlight-html"><div class="highlight"><pre><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/pastebin/pastes/&quot;</span><span class="nt">&gt;</span>View All<span class="nt">&lt;/a&gt;</span>
</pre></div>
</div>
<p>It also takes arguments:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_detail</span> <span class="nv">paste.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;</span><span class="cp">{{</span> <span class="nv">paste</span> <span class="cp">}}</span><span class="x">&lt;/a&gt;</span>
</pre></div>
</div>
<p>would output</p>
<div class="highlight-html"><div class="highlight"><pre><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/pastebin/paste/9&quot;</span><span class="nt">&gt;</span>Sample Paste<span class="nt">&lt;/a&gt;</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You must make sure the correct urlconf entry for the give url exists. If the url entry
does not exist, or the number of arguments does not match, this templatetag will raise a
<tt class="docutils literal"><span class="pre">NoReverseMatch</span></tt> exception.</p>
</div>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">csrf_token</span></tt></p>
<p>This is a security related tag used in forms to prevent cross site request forgery.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">include</span> <span class="pre">&lt;template&gt;</span></tt></p>
<p>This will simply include any file that can be found by the <tt class="docutils literal"><span class="pre">TEMPLATE_LOADERS</span></tt> where it is called</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">extends</span> <span class="pre">&lt;template&gt;</span></tt></p>
<p>This will extend another template and provides template inheritance. You can have a <tt class="docutils literal"><span class="pre">base</span></tt> template and
have other specific template extend the <tt class="docutils literal"><span class="pre">base</span></tt> template.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">block</span></tt> and <tt class="docutils literal"><span class="pre">endblock</span></tt></p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">blocks</span></tt> are used to customize the <tt class="docutils literal"><span class="pre">base</span></tt> page from a <tt class="docutils literal"><span class="pre">child</span></tt> page. If the <tt class="docutils literal"><span class="pre">base</span></tt> page defines a block called</dt>
<dd><p class="first last"><tt class="docutils literal"><span class="pre">head</span></tt>, the child page can override that block with its own contents.</p>
</dd>
</dl>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">load</span></tt></p>
<p>This is used to load custom templatetags. More about writing and using custom templatetags later.</p>
</li>
</ul>
<p>We will see later how to add custom templatetags.</p>
</div>
<div class="section" id="filters">
<h3>Filters:<a class="headerlink" href="#filters" title="Permalink to this headline">¶</a></h3>
<p>Filters are simple functions which operate on a template variable and manipulate them.</p>
<p>For example in our previous template:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">Hello </span><span class="cp">{{</span> <span class="nv">username</span><span class="o">|</span><span class="nf">capfirst</span> <span class="cp">}}</span><span class="x"></span>
</pre></div>
</div>
<p>Here <tt class="docutils literal"><span class="pre">capfirst</span></tt> is a filter that will capitalize the first char our <tt class="docutils literal"><span class="pre">username</span></tt></p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Reference of built-in templatetags and filters:
<a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/templates/builtins/">http://docs.djangoproject.com/en/1.2/ref/templates/builtins/</a></p>
</div>
</div>
<div class="section" id="templates-are-not-meant-for-programming">
<h3>Templates are not meant for programming:<a class="headerlink" href="#templates-are-not-meant-for-programming" title="Permalink to this headline">¶</a></h3>
<p>One of the core django philosophy is that templates are meant for rendering the context and
optionally making a few aesthetic changes only. Templates should not be used for handling
complex queries or operations. This is also useful to keep the programming and designing aspects
of the website separate. Template language should be easy enough to be written by designers.</p>
</div>
</div>
<div class="section" id="generic-views-commonly-used-views">
<h2>Generic views - commonly used views:<a class="headerlink" href="#generic-views-commonly-used-views" title="Permalink to this headline">¶</a></h2>
<div class="section" id="views">
<h3>Views:<a class="headerlink" href="#views" title="Permalink to this headline">¶</a></h3>
<p>Views are just functions which take the <tt class="docutils literal"><span class="pre">HttpRequest</span></tt> object, and some optional arguments,
then do some work and return a <tt class="docutils literal"><span class="pre">HttpResponse</span></tt> page. Use <tt class="docutils literal"><span class="pre">HttpResponseRedirect</span></tt> to redirect
to some other <tt class="docutils literal"><span class="pre">url</span></tt> or <tt class="docutils literal"><span class="pre">HttpResponseForbidden</span></tt> to return a <tt class="docutils literal"><span class="pre">403</span> <span class="pre">Forbidden</span></tt> response.</p>
<p>By convention, all of an app&#8217;s views would be written in &lt;app&gt;/views.py</p>
<p>A simple example to return &#8220;Hello World!&#8221; string response:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="s">&quot;Hello World!&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>To render a template to response one would do:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Context</span><span class="p">,</span> <span class="n">loader</span>
<span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">&quot;hello_world.html&quot;</span><span class="p">)</span>
<span class="n">context</span> <span class="o">=</span> <span class="n">Context</span><span class="p">({</span><span class="s">&quot;username&quot;</span><span class="p">:</span> <span class="s">&quot;Monty Python&quot;</span><span class="p">})</span>
<span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
</pre></div>
</div>
<p>But there&#8217;s a simpler way:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">&quot;hello_world.html&quot;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&quot;username&quot;</span><span class="p">:</span> <span class="s">&quot;Monty Python&quot;</span> <span class="p">})</span>
</pre></div>
</div>
</div>
<div class="section" id="generic-views">
<h3>Generic Views:<a class="headerlink" href="#generic-views" title="Permalink to this headline">¶</a></h3>
<p>Generic views are commonly used view patterns that are shipped with django to make
common operations such a list, detail, create, update delete easy. To do these operations,
we need not even write any views, we can use generic views by passing the proper arguments.</p>
<p>We will be using the <tt class="docutils literal"><span class="pre">create_update</span></tt> and <tt class="docutils literal"><span class="pre">list_detail</span></tt> generic views in this chapter</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">reference: <a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/generic-views/">http://docs.djangoproject.com/en/dev/ref/generic-views/</a></p>
</div>
</div>
<div class="section" id="create-update-create-object">
<h3><tt class="docutils literal"><span class="pre">create_update.create_object</span></tt><a class="headerlink" href="#create-update-create-object" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">create_object</span></tt> generic view is used to render the object creation page with the
object form, perform form validation and save valid objects to the database.</p>
<p>It takes a <tt class="docutils literal"><span class="pre">model</span></tt> argument which is the model that has to be created. By default, it renders
to template with the name <tt class="docutils literal"><span class="pre">&lt;app&gt;/&lt;model&gt;_form.html</span></tt>. This can be changed using the <tt class="docutils literal"><span class="pre">template_name</span></tt>
argument. (this applies to all generic views listed here)</p>
<p>The view provides <tt class="docutils literal"><span class="pre">form</span></tt> variable in the context. This is the generated ModelForm of the <tt class="docutils literal"><span class="pre">model</span></tt>.</p>
</div>
<div class="section" id="create-update-update-object">
<h3><tt class="docutils literal"><span class="pre">create_update.update_object</span></tt><a class="headerlink" href="#create-update-update-object" title="Permalink to this headline">¶</a></h3>
<p>In addition to the <tt class="docutils literal"><span class="pre">model</span></tt> argument, the <tt class="docutils literal"><span class="pre">update_object</span></tt> generic view also requires a <tt class="docutils literal"><span class="pre">object_id</span></tt>
argument which is the <tt class="docutils literal"><span class="pre">id</span></tt> of the object to be updated. This also renders to <tt class="docutils literal"><span class="pre">&lt;app&gt;/&lt;model&gt;_form.html</span></tt> template.</p>
<p>In addition to the <tt class="docutils literal"><span class="pre">form</span></tt> variable, this view also provides the <tt class="docutils literal"><span class="pre">object</span></tt> that is being edited to the context.</p>
</div>
<div class="section" id="create-update-delete-object">
<h3><tt class="docutils literal"><span class="pre">create_update.delete_object</span></tt><a class="headerlink" href="#create-update-delete-object" title="Permalink to this headline">¶</a></h3>
<p>In addition to both the above arguments, this view also requires a <tt class="docutils literal"><span class="pre">post_delete_redirect</span></tt> argument
which is the url to redirect after deleting. If called using the <tt class="docutils literal"><span class="pre">GET</span></tt> method, this view will
redirect to <tt class="docutils literal"><span class="pre">&lt;app&gt;/&lt;model&gt;_confirm_delete.html</span></tt> template. To actually delete the object, this
view needs to be called using the <tt class="docutils literal"><span class="pre">POST</span></tt> method. This is in accordance with the best practices that
<tt class="docutils literal"><span class="pre">GET</span></tt> requests should not modify any data.</p>
</div>
<div class="section" id="list-detail-object-list">
<h3><tt class="docutils literal"><span class="pre">list_detail.object_list</span></tt><a class="headerlink" href="#list-detail-object-list" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">object_list</span></tt> generic view shows the list of the <tt class="docutils literal"><span class="pre">queryset</span></tt>, where <tt class="docutils literal"><span class="pre">queryset</span></tt> is the
queryset containing the objects we want to list.</p>
<p>It renders the <tt class="docutils literal"><span class="pre">&lt;app&gt;/&lt;model&gt;_list.html</span></tt> template and provides <tt class="docutils literal"><span class="pre">object_list</span></tt> context
variable by default.</p>
</div>
<div class="section" id="list-detail-object-detail">
<h3><tt class="docutils literal"><span class="pre">list_detail.object_detail</span></tt><a class="headerlink" href="#list-detail-object-detail" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">object_detail</span></tt> generic view show details about a particular object. It takes the <tt class="docutils literal"><span class="pre">queryset</span></tt> to fetch
the <tt class="docutils literal"><span class="pre">object_id</span></tt> from and returns <tt class="docutils literal"><span class="pre">object</span></tt> in the context.</p>
<p>It renders to <tt class="docutils literal"><span class="pre">&lt;app&gt;/&lt;model&gt;_detail.html</span></tt> by default.</p>
</div>
</div>
<div class="section" id="designing-a-pastebin-app">
<h2>Designing a pastebin app:<a class="headerlink" href="#designing-a-pastebin-app" title="Permalink to this headline">¶</a></h2>
<p>In this chapter we will be designing a simple pastebin. Our pastebin will be able to</p>
<blockquote>
<ul class="simple">
<li>Allow users to paste some text</li>
<li>Allow users to edit or delete the text</li>
<li>Allow users to view all texts</li>
<li>Clean up texts older than a day</li>
</ul>
</blockquote>
<p>Some &#8216;views&#8217; that the user will see are</p>
<blockquote>
<ul class="simple">
<li>A list view of all recent texts</li>
<li>A detail view of any selected text</li>
<li>An entry/edit form for a text</li>
<li>A view to delete a text</li>
</ul>
</blockquote>
<p>Since the list and detail views are fairly common in most apps,
django ships with a set of &#8216;generic views&#8217; that can be used in
our app. We would be particularly interested in the following generic
views</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">django.views.generic.create_update.create_object</span></tt></li>
<li><tt class="docutils literal"><span class="pre">django.views.generic.create_update.update_object</span></tt></li>
<li><tt class="docutils literal"><span class="pre">django.views.generic.create_update.delete_object</span></tt></li>
<li><tt class="docutils literal"><span class="pre">django.views.generic.list_detail.object_list</span></tt></li>
<li><tt class="docutils literal"><span class="pre">django.views.generic.list_detail.object_detail</span></tt></li>
</ul>
</blockquote>
<p>Our work flow for this app would be</p>
<blockquote>
<ul class="simple">
<li>sketch the models</li>
<li>route urls to generic views</li>
<li>use generic views with our models</li>
<li>write the templates to use generic views</li>
</ul>
</blockquote>
<p>So let&#8217;s dive in:</p>
</div>
<div class="section" id="sketch-the-models">
<h2>Sketch the models:<a class="headerlink" href="#sketch-the-models" title="Permalink to this headline">¶</a></h2>
<p>We have only one object to store to the database which is
the text pasted by the user. Let&#8217;s call this Paste.</p>
<p>Some things our Paste model would need to handle are</p>
<blockquote>
<ul class="simple">
<li>Text pasted by the user</li>
<li>Optional file name</li>
<li>Created time</li>
<li>Updated time</li>
</ul>
</blockquote>
<p>The time fields would be useful for getting &#8216;latest&#8217; or &#8216;recently updated&#8217;
pastes.</p>
<p>So let&#8217;s get started:</p>
<div class="highlight-python"><pre>python manage.py startapp pastebin</pre>
</div>
<p>In pastebin/models.py</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="c"># Create your models here.</span>
<span class="k">class</span> <span class="nc">Paste</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">text</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">40</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">created_on</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">updated_on</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now</span><span class="o">=</span><span class="bp">True</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">name</span> <span class="ow">or</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<ul class="last simple">
<li>auto_now_add automatically adds current time to the created_on
field when an object is added.</li>
<li>auto_now is similar to the above, but it adds the current time to
the updated_on field each time an object is saved.</li>
<li>the id field is primary key which is autocreated by django. Since
name is optional, we fall back to the id which is guaranteed.</li>
</ul>
</div>
<p>Adding our app to the project</p>
<div class="highlight-python"><pre>INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.markup',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
'cd_library',
'pastebin',
</pre>
</div>
<p>And syncdb&#8217;ing:</p>
<div class="highlight-python"><pre>python manage.py syncdb</pre>
</div>
<p>which returns:</p>
<div class="highlight-python"><pre>Creating table pastebin_paste
No fixtures found.</pre>
</div>
<p>There, we have our pastebin models ready.</p>
</div>
<div class="section" id="configuring-urls">
<h2>Configuring urls:<a class="headerlink" href="#configuring-urls" title="Permalink to this headline">¶</a></h2>
<p>We have already seen how to include the admin urls in urls.py. But now, we want to have
our app take control of the urls and direct them to generic views. Here&#8217;s how</p>
<p>Let&#8217;s create urls.py in our app. Now our pastebin/urls.py should look like</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">models</span> <span class="kn">import</span> <span class="n">Paste</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s">r&#39;$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">}),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Notes:</p>
<ul>
<li><p class="first">Each urlpatterns line is a mapping of urls to views</p>
<p><tt class="docutils literal"><span class="pre">(r'^$',</span> <span class="pre">'django.views.generic.create_update.create_object',</span> <span class="pre">{</span> <span class="pre">'model':</span> <span class="pre">Paste</span> <span class="pre">}),</span></tt></p>
</li>
<li><p class="first">Here the url is <tt class="docutils literal"><span class="pre">r'^$'</span></tt> which is a regular expression that will be matched with the incoming request.
If a match is found, the request is forwarded to the corresponding view.</p>
</li>
<li><p class="first">The third value is the arguments passed to the <tt class="docutils literal"><span class="pre">create_object</span></tt> view. The view will use the <tt class="docutils literal"><span class="pre">model</span></tt>
argument to generate a form and save it to the database. In our case, this is the <tt class="docutils literal"><span class="pre">Paste</span></tt> model</p>
</li>
</ul>
<p>Let&#8217;s tell the project to include our app&#8217;s urls</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="c"># Uncomment the next two lines to enable the admin:</span>
<span class="kn">from</span> <span class="nn">django.contrib</span> <span class="kn">import</span> <span class="n">admin</span>
<span class="n">admin</span><span class="o">.</span><span class="n">autodiscover</span><span class="p">()</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="c"># Example:</span>
<span class="c"># (r&#39;^djen_project/&#39;, include(&#39;djen_project.foo.urls&#39;)),</span>
<span class="c"># Uncomment the admin/doc line below and add &#39;django.contrib.admindocs&#39; </span>
<span class="c"># to INSTALLED_APPS to enable admin documentation:</span>
<span class="c"># (r&#39;^admin/doc/&#39;, include(&#39;django.contrib.admindocs.urls&#39;)),</span>
<span class="c"># Uncomment the next line to enable the admin:</span>
<span class="p">(</span><span class="s">r&#39;^accounts/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;registration.backends.default.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^admin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">urls</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^pastebin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;pastebin.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^blog/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;blog.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^wiki/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;wiki.urls&#39;</span><span class="p">)),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Now django knows to forward urls starting with <tt class="docutils literal"><span class="pre">/pastebin</span></tt> to the pastebin app. All urls relative to this url
will be handled by the pastebin app. That&#8217;s great for reusability.</p>
<p>If you try to open <a class="reference external" href="http://127.0.0.1/pastebin">http://127.0.0.1/pastebin</a> at this point, you will be greeted with a TemplateDoesNotExist error.
If you observe, the error message says that django cannot find <tt class="docutils literal"><span class="pre">pastebin/paste_form.html</span></tt>. Usually getting this error means that
django was not able to find that file.</p>
<p>The default template used by create_object is &#8216;&lt;app&gt;/&lt;model&gt;_form.html&#8217;. In our case this would be <tt class="docutils literal"><span class="pre">pastebin/paste_form.html</span></tt>.</p>
<p>Let&#8217;s create this template. In <tt class="docutils literal"><span class="pre">pastebin/templates/pastebin/paste_form.html</span></tt>:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;h1&gt;Create new Paste&lt;/h1&gt;</span>
<span class="x">&lt;form action=&quot;&quot; method=&quot;POST&quot;&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">csrf_token</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;table&gt;</span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">form.as_table</span> <span class="cp">}}</span><span class="x"></span>
<span class="x"> &lt;/table&gt;</span>
<span class="x"> &lt;input type=&quot;submit&quot; name=&quot;create&quot; value=&quot;Create&quot;&gt;</span>
<span class="x">&lt;/form&gt;</span>
<span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_list</span> <span class="cp">%}</span><span class="x">&quot;&gt;View All&lt;/a&gt;</span>
</pre></div>
</div>
<p>Observe that:</p>
<ul class="simple">
<li>the create_object generic view has provided a <tt class="docutils literal"><span class="pre">form</span></tt> context variable.</li>
<li>the form has been autogenerated by django&#8217;s forms library by using the <tt class="docutils literal"><span class="pre">Paste</span></tt> model</li>
<li>to display the form, all you have to do is render the <tt class="docutils literal"><span class="pre">form</span></tt> variable</li>
<li>form has a method <tt class="docutils literal"><span class="pre">as_table</span></tt> that will render it as table, other options are <tt class="docutils literal"><span class="pre">as_p</span></tt>, <tt class="docutils literal"><span class="pre">as_ul</span></tt>
for enclosing the form in <tt class="docutils literal"><span class="pre">&lt;p&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;ul&gt;</span></tt> tags respectively</li>
<li>form does not output the form tags or the submit button, so we will have to write them down
in the template</li>
<li>you need to include <tt class="docutils literal"><span class="pre">csrf_token</span></tt> tag in every form posted to a local view. Django uses this to prevent
cross site request forgery</li>
<li>the generated form includes validation based on the model fields</li>
</ul>
<p>Now, we need a page to redirect successful submissions to. We can use the detail view page of a paste here.</p>
<p>For this, we will use the <tt class="docutils literal"><span class="pre">django.views.generic.list_detail.object_detail</span></tt> generic view:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">models</span> <span class="kn">import</span> <span class="n">Paste</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">}),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^paste/(?P&lt;object_id&gt;\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.list_detail.object_detail&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;queryset&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_detail&#39;</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Using this generic view we will be able to display the details about the paste object with a given id. Note that:</p>
<ul class="simple">
<li>object_id and queryset are the arguments passed to object_detail view</li>
<li>we are naming this view using the url constructor and passing the <tt class="docutils literal"><span class="pre">name</span></tt> argument. This name can be referred to
from views or templates and helps in keeping this DRY.</li>
<li>the object_detail view will render the <tt class="docutils literal"><span class="pre">pastebin/paste_detail.html</span></tt> template by default. We need to write down this
template for this view to work.</li>
</ul>
<p>In <tt class="docutils literal"><span class="pre">pastebin/templates/pastebin/paste_detail.html</span></tt>:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;label&gt;Paste Details: &lt;/label&gt;</span>
<span class="x">&lt;p&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;ID&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.id</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Name&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.name</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Text&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.text</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Created&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.created_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Modified&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.updated_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x">&lt;/p&gt;</span>
</pre></div>
</div>
<p>Now, that we have a create view and a detail view, we just need to glue them together. We can do this in two ways:</p>
<ul class="simple">
<li>pass the <tt class="docutils literal"><span class="pre">post_save_redirect</span></tt> argument in <tt class="docutils literal"><span class="pre">create_object</span></tt> view</li>
<li>set the <tt class="docutils literal"><span class="pre">get_absolute_url</span></tt> property of our Paste model to its detail view. <tt class="docutils literal"><span class="pre">create_object</span></tt> view will call the object&#8217;s
<tt class="docutils literal"><span class="pre">get_absolute_url</span></tt> by default</li>
</ul>
<p>I would choose the latter because it is more general. To do this, change your Paste model and add the get_absolute_url property:</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="c"># Create your models here.</span>
<span class="k">class</span> <span class="nc">Paste</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">text</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">40</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">created_on</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">updated_on</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now</span><span class="o">=</span><span class="bp">True</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">name</span> <span class="ow">or</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="nd">@models.permalink</span>
<span class="k">def</span> <span class="nf">get_absolute_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s">&#39;pastebin_paste_detail&#39;</span><span class="p">,</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">])</span>
</pre></div>
</div>
<p>Note that:</p>
<ul class="simple">
<li>We could have returned <tt class="docutils literal"><span class="pre">'/pastebin/paste/%s'</span> <span class="pre">%(self.id)'</span></tt> but it would mean defining the same url twice and it violates the DRY principle.
Using the <tt class="docutils literal"><span class="pre">models.permalink</span></tt> decorator, we can tell django to call the url named <tt class="docutils literal"><span class="pre">pastebin_paste_detail</span></tt> with the parameter <tt class="docutils literal"><span class="pre">id</span></tt></li>
</ul>
<p>And so, we are ready with the create object and object detail views. Try submitting any pastes and you should be redirected to the details of
your paste.</p>
<p>Now, on to our next generic view, which is object list:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">models</span> <span class="kn">import</span> <span class="n">Paste</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">}),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^paste/(?P&lt;object_id&gt;\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.list_detail.object_detail&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;queryset&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_detail&#39;</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^pastes/$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.list_detail.object_list&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;queryset&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="p">}),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>This is simpler than the detail view, since it does not take any arguments in the url. The default template for this view is <tt class="docutils literal"><span class="pre">pastebin/paste_list.html</span></tt>
so let&#8217;s fill that up with:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">object_list</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;h1&gt;Recent Pastes:&lt;/h1&gt;</span>
<span class="x">&lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">paste</span> <span class="k">in</span> <span class="nv">object_list</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_detail</span> <span class="nv">paste.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;</span><span class="cp">{{</span> <span class="nv">paste</span> <span class="cp">}}</span><span class="x">&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;/ul&gt;</span>
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;h1&gt;No recent pastes&lt;/h1&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
</div>
<p>Note that</p>
<ul class="simple">
<li>We have used the <tt class="docutils literal"><span class="pre">url</span></tt> template tag and passed our named view i.e. <tt class="docutils literal"><span class="pre">pastebin_paste_detail</span></tt> to get the url to a specific paste</li>
</ul>
<p>Similarly, our update and delete generic views would look like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="c">#from django.core.urlresolvers import reverse</span>
<span class="kn">from</span> <span class="nn">models</span> <span class="kn">import</span> <span class="n">Paste</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.create_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_create&#39;</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^paste/edit/(?P&lt;object_id&gt;\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.update_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_edit&#39;</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^paste/delete/(?P&lt;object_id&gt;\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.create_update.delete_object&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;model&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="p">,</span> <span class="s">&#39;post_delete_redirect&#39;</span><span class="p">:</span> <span class="s">&#39;/pastebin/pastes&#39;</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_delete&#39;</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^paste/(?P&lt;object_id&gt;\d+)$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.list_detail.object_detail&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;queryset&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_detail&#39;</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^pastes/$&#39;</span><span class="p">,</span> <span class="s">&#39;django.views.generic.list_detail.object_list&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="s">&#39;queryset&#39;</span><span class="p">:</span> <span class="n">Paste</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> <span class="p">},</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;pastebin_paste_list&#39;</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>Note that the <tt class="docutils literal"><span class="pre">delete_object</span></tt> generic view requires an argument called <tt class="docutils literal"><span class="pre">post_delete_redirect</span></tt> which will be used to redirect the user
after deleting the object.</p>
<p>We have used update_object, delete_object for the update/delete views respectively. Let&#8217;s link these urls from the detail page:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;div class=&quot;messages&quot;&gt;</span>
<span class="x"> &lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">message</span> <span class="k">in</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li class=&quot;</span><span class="cp">{{</span> <span class="nv">message.tag</span> <span class="cp">}}</span><span class="x">&quot;&gt;</span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">message</span> <span class="cp">}}</span><span class="x"> </span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;/ul&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;h1&gt;Paste Details: &lt;/h1&gt;</span>
<span class="x">&lt;p&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;ID&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.id</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Name&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.name</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Text&lt;/label&gt;</span>
<span class="x"> &lt;textarea rows=&quot;10&quot; cols=&quot;50&quot; OnClick=&quot;this.select();&quot; readonly=&quot;true&quot;&gt;</span><span class="cp">{{</span> <span class="nv">object.text</span> <span class="cp">}}</span><span class="x">&lt;/textarea&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Created&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.created_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Modified&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.updated_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x">&lt;/p&gt;</span>
<span class="x">&lt;h2&gt;Actions&lt;/h2&gt;</span>
<span class="x"> &lt;ul&gt;</span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_edit</span> <span class="nv">object.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;Edit this paste&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_delete</span> <span class="nv">object.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;Delete this paste&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> &lt;/ul&gt;</span>
<span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_list</span> <span class="cp">%}</span><span class="x">&quot;&gt;View All&lt;/a&gt;</span>
</pre></div>
</div>
<p>Note that the delete view redirects to a confirmation page whose template name is <tt class="docutils literal"><span class="pre">paste_confirm_delete.html</span></tt> if called using GET method.
Once in the confirmation page, we need need to call the same view with a POST method. The view will delete the object and pass a message using
the messages framework.</p>
<div class="highlight-django"><div class="highlight"><pre><span class="x">&lt;h1&gt;Really delete paste </span><span class="cp">{{</span> <span class="nv">object</span> <span class="cp">}}</span><span class="x">?&lt;/h1&gt;</span>
<span class="x">&lt;h2&gt;This action cannot be undone&lt;/h2&gt;</span>
<span class="x">&lt;form action=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_delete</span> <span class="nv">object.id</span> <span class="cp">%}</span><span class="x">&quot; method=&quot;POST&quot;&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">csrf_token</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;input type=&quot;submit&quot; value=&quot;Delete&quot;&gt;</span>
<span class="x">&lt;/form&gt;</span>
</pre></div>
</div>
<p>Let&#8217;s handle the message and display it in the redirected page.</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;div class=&quot;messages&quot;&gt;</span>
<span class="x"> &lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">message</span> <span class="k">in</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li class=&quot;</span><span class="cp">{{</span> <span class="nv">message.tag</span> <span class="cp">}}</span><span class="x">&quot;&gt;</span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">message</span> <span class="cp">}}</span><span class="x"> </span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;/ul&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">if</span> <span class="nv">object_list</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;h1&gt;Recent Pastes:&lt;/h1&gt;</span>
<span class="x">&lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">paste</span> <span class="k">in</span> <span class="nv">object_list</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_detail</span> <span class="nv">paste.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;</span><span class="cp">{{</span> <span class="nv">paste</span> <span class="cp">}}</span><span class="x">&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;/ul&gt;</span>
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;h1&gt;No recent pastes&lt;/h1&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_create</span> <span class="cp">%}</span><span class="x">&quot;&gt;Create new&lt;/a&gt;</span>
</pre></div>
</div>
<p>While we are at it, Let&#8217;s also include the messages in paste detail page, where create/update view sends the messages:</p>
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;div class=&quot;messages&quot;&gt;</span>
<span class="x"> &lt;ul&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">message</span> <span class="k">in</span> <span class="nv">messages</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;li class=&quot;</span><span class="cp">{{</span> <span class="nv">message.tag</span> <span class="cp">}}</span><span class="x">&quot;&gt;</span>
<span class="x"> </span><span class="cp">{{</span> <span class="nv">message</span> <span class="cp">}}</span><span class="x"> </span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> &lt;/ul&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="x">&lt;h1&gt;Paste Details: &lt;/h1&gt;</span>
<span class="x">&lt;p&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;ID&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.id</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Name&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.name</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Text&lt;/label&gt;</span>
<span class="x"> &lt;textarea rows=&quot;10&quot; cols=&quot;50&quot; OnClick=&quot;this.select();&quot; readonly=&quot;true&quot;&gt;</span><span class="cp">{{</span> <span class="nv">object.text</span> <span class="cp">}}</span><span class="x">&lt;/textarea&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Created&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.created_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x"> &lt;div&gt;</span>
<span class="x"> &lt;label&gt;Modified&lt;/label&gt;</span>
<span class="x"> &lt;span&gt;</span><span class="cp">{{</span> <span class="nv">object.updated_on</span> <span class="cp">}}</span><span class="x">&lt;/span&gt;</span>
<span class="x"> &lt;/div&gt;</span>
<span class="x">&lt;/p&gt;</span>
<span class="x">&lt;h2&gt;Actions&lt;/h2&gt;</span>
<span class="x"> &lt;ul&gt;</span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_edit</span> <span class="nv">object.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;Edit this paste&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> &lt;li&gt;</span>
<span class="x"> &lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_delete</span> <span class="nv">object.id</span> <span class="cp">%}</span><span class="x">&quot;&gt;Delete this paste&lt;/a&gt;</span>
<span class="x"> &lt;/li&gt;</span>
<span class="x"> &lt;/ul&gt;</span>
<span class="x">&lt;a href=&quot;</span><span class="cp">{%</span> <span class="k">url</span> <span class="nv">pastebin_paste_list</span> <span class="cp">%}</span><span class="x">&quot;&gt;View All&lt;/a&gt;</span>
</pre></div>
</div>
<p>So we now have pages to create, update, delete and view all pastes.</p>
<p>Now, for better maintenance, we would like to delete all pastes that have not been updated in a day using an script.
We will use django&#8217;s custom management scripts for this.</p>
</div>
<div class="section" id="writing-custom-management-scripts">
<h2>Writing custom management scripts:<a class="headerlink" href="#writing-custom-management-scripts" title="Permalink to this headline">¶</a></h2>
<p>Just like other manage.py subcommands such as <tt class="docutils literal"><span class="pre">syncdb</span></tt>, <tt class="docutils literal"><span class="pre">shell</span></tt>, <tt class="docutils literal"><span class="pre">startapp</span></tt> and <tt class="docutils literal"><span class="pre">runserver</span></tt>, we can have custom subcommands to
help us maintain the app.</p>
<p>For our subcommand to be registered with manage.py, we need the following structure in our app:</p>
<div class="highlight-python"><pre>.
|-- __init__.py
|-- management
| |-- commands
| | `-- __init__.py
| `-- __init__.py
|-- models.py
|-- templates
|-- tests.py
|-- urls.py
`-- views.py</pre>
</div>
<p>All scripts inside <tt class="docutils literal"><span class="pre">management/commands/</span></tt> will be used as custom subcommands. Let&#8217;s create <tt class="docutils literal"><span class="pre">delete_old.py</span></tt> subcommand:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">django.core.management.base</span> <span class="kn">import</span> <span class="n">NoArgsCommand</span>
<span class="kn">from</span> <span class="nn">pastebin.models</span> <span class="kn">import</span> <span class="n">Paste</span>
<span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="n">NoArgsCommand</span><span class="p">):</span>
<span class="n">help</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s"> deletes pastes not updated in last 24 hrs</span>
<span class="s"> Use this subcommand in a cron job</span>
<span class="s"> to clear older pastes</span>
<span class="s"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">handle_noargs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">options</span><span class="p">):</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">yesterday</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">old_pastes</span> <span class="o">=</span> <span class="n">Paste</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">updated_on__lte</span><span class="o">=</span><span class="n">yesterday</span><span class="p">)</span>
<span class="n">old_pastes</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre></div>
</div>
<p>Here:</p>
<ul class="simple">
<li>We subclass either of the <tt class="docutils literal"><span class="pre">NoArgsCommand</span></tt>, <tt class="docutils literal"><span class="pre">LabelCommand</span></tt> or <tt class="docutils literal"><span class="pre">AppCommand</span></tt> from <tt class="docutils literal"><span class="pre">django.core.management.base</span></tt>. <tt class="docutils literal"><span class="pre">NoArgsCommand</span></tt>
suits our need because we dont need to pass any arguments to this subcommand.</li>
<li><tt class="docutils literal"><span class="pre">handle_noargs</span></tt> will be called when the script runs. This would be <tt class="docutils literal"><span class="pre">handle</span></tt> for other Command types.</li>
<li>We have used the <tt class="docutils literal"><span class="pre">lte</span></tt> lookup on <tt class="docutils literal"><span class="pre">updated_on</span></tt> field to get all posts older than a day. Then we delete them using <tt class="docutils literal"><span class="pre">delete</span></tt> method
on the queryset.</li>
</ul>
<p>You can test if the subcommand works by doing:</p>
<div class="highlight-python"><pre>python manage.py delete_old</pre>
</div>
<p>Now we can configure this script to run daily using cronjob or something similar.</p>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="chapter4.html" title="Chapter 4. Building a Blog"
>next</a> |</li>
<li class="right" >
<a href="chapter2.html" title="Chapter 2. Building a personal CD library."
>previous</a> |</li>
<li><a href="index.html">Djen of Django</a> &raquo;</li>
</ul>
</div>
<div id="disqus_thread"></div><script type="text/javascript" src="http://disqus.com/forums/agiliq/embed.js"></script><noscript><a href="http://disqus.com/forums/agiliq/?url=ref">View the discussion thread.</a></noscript><a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
<div class="footer">
&copy; Copyright 2010, Agiliq.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1pre.
<script type="text/javascript">
//<![CDATA[
(function() {
var links = document.getElementsByTagName('a');
var query = '?';
for(var i = 0; i < links.length; i++) {
if(links[i].href.indexOf('#disqus_thread') >= 0) {
query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
}
}
document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/agiliq/get_num_replies.js' + query + '"></' + 'script>');
})();
//]]>
</script>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-xxxxxx-xx");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.