<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>/var/</title><link>http://spapas.github.io/</link><description>Various programming stuff</description><atom:link href="http://spapas.github.io/feeds/all.rss.xml" rel="self"></atom:link><lastBuildDate>Tue, 22 Dec 2015 15:20:00 +0200</lastBuildDate><item><title>Ajax data with Fixed Data Table for React</title><link>http://spapas.github.io/2015/12/22/ajax-with-react-fixed-data-table/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#our-project" id="id2"&gt;Our&amp;nbsp;project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#how-fixeddatatable-gets-its-data" id="id3"&gt;How FixedDataTable gets its&amp;nbsp;data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ajaxcell-non-working-version-1" id="id4"&gt;AjaxCell: Non working version&amp;nbsp;1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ajaxcell-non-working-version-2" id="id5"&gt;AjaxCell: Non working version&amp;nbsp;2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ajaxcell-non-working-version-3" id="id6"&gt;AjaxCell: Non working version&amp;nbsp;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ajaxcell-final-version" id="id7"&gt;AjaxCell: Final&amp;nbsp;version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-table-container-component" id="id8"&gt;The Table container&amp;nbsp;component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#some-enchancements" id="id9"&gt;Some&amp;nbsp;enchancements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conslusion" id="id10"&gt;Conslusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://facebook.github.io/fixed-data-table/"&gt;FixedDataTable&lt;/a&gt; is a nice React component from Facebook that is used to render tabular data.
Its main characteristic is that it can handle many rows without sacrificing performance, however
probably due to this fact I was not able to find any examples for loading data using Ajax - all
examples I was able to find had the data already loaded (or created on the&amp;nbsp;fly).&lt;/p&gt;
&lt;p&gt;So, although FixedDataTable is able to handle many rows, I am against transfering all of them to the user
whenever our page loads since at most one page of data will be shown on screen (30 rows or so ?) -
any other actions (filtering, sorting, aggregate calculations etc) should be done on the&amp;nbsp;server.&lt;/p&gt;
&lt;p&gt;In the following I will present a simple, react-only example with a FixedDataTable that can be
used with server-side, asynchronous, paginated&amp;nbsp;data.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="our-project"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Our&amp;nbsp;project&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s see an example of what we&amp;#8217;ll&amp;nbsp;build:&lt;/p&gt;
&lt;img alt="Our project" src="/images/ajax_fixed_data_tables.gif" style="width: 600px;" /&gt;
&lt;p&gt;As a source of the data I&amp;#8217;ve used the &lt;a class="reference external" href="http://swapi.co/"&gt;Star Wars &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; and specifically its &lt;a class="reference external" href="http://swapi.co/documentation#people"&gt;People &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; by issuing
requests to &lt;a class="reference external" href="http://swapi.co/api/people/?format=json"&gt;http://swapi.co/api/people/?format=json&lt;/a&gt;. This will return an array of people from the
star wars universe in &lt;span class="caps"&gt;JSON&lt;/span&gt; format - the results are paginated with a page size of 10 (and we can switch
to another page using the extra &lt;tt class="docutils literal"&gt;page=&lt;/tt&gt; request&amp;nbsp;parameter).&lt;/p&gt;
&lt;p&gt;I will use es6 with the object spread operator (as described in &lt;a class="reference external" href="http://spapas.github.io/2015/11/16/using-browserify-es6/"&gt;a previous article&lt;/a&gt;)
to write the code, using a single main.js as a source which will be transpiled to &lt;tt class="docutils literal"&gt;dist/bundle.js&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The placeholder &lt;span class="caps"&gt;HTML&lt;/span&gt; for our application&amp;nbsp;is:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;Hello Ajax Fixed Data Table!&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href='https://cdnjs.cloudflare.com/ajax/libs/fixed-data-table/0.6.0/fixed-data-table.min.css'&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src='dist/bundle.js' &amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The versions that are used are react 14.3 and fixed-data-table 0.6.0. You can find this project in github &amp;#64;
&lt;a class="reference external" href="https://github.com/spapas/react-tables"&gt;https://github.com/spapas/react-tables&lt;/a&gt; &amp;#8212; tag name &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fixed-data-table-ajax&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-fixeddatatable-gets-its-data"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;How FixedDataTable gets its&amp;nbsp;data&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The data of a &lt;tt class="docutils literal"&gt;FixedDataTable&lt;/tt&gt; component is defined through a number of &lt;tt class="docutils literal"&gt;Column&lt;/tt&gt; components
and specifically, the &lt;tt class="docutils literal"&gt;cell&lt;/tt&gt; attribute of that component which sould either return be a static string
to be displayed in that column or a React component (usually a &lt;tt class="docutils literal"&gt;Cell&lt;/tt&gt;) that will be displayed in
that column or even a function that returns a string or a react component. The function (or component)
passed to &lt;tt class="docutils literal"&gt;cell&lt;/tt&gt; will have an object with a &lt;tt class="docutils literal"&gt;rowIndex&lt;/tt&gt; attribute (among others) as a parameter,
for example the&amp;nbsp;following&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;Column
  header={&amp;lt;Cell&amp;gt;Url&amp;lt;/Cell&amp;gt;}
  cell={props =&amp;gt; props.rowIndex}
  width={200}
/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;will just display the rowIndex for each&amp;nbsp;cell.&lt;/p&gt;
&lt;p&gt;So we can see that for each cell that FixedDataTable wants to display it will use its corresponding
&lt;tt class="docutils literal"&gt;cell&lt;/tt&gt; attribute.
So, a general though if we wanted to support asynchronous, paginated data
is to check the rowIndex and retrieve the correct page asynchronously.
This would lead to a difficulty: What should the &lt;tt class="docutils literal"&gt;cell&lt;/tt&gt; function return? We&amp;#8217;ll try to resolve this
using an &lt;tt class="docutils literal"&gt;AjaxCell&lt;/tt&gt; function that should return a react componet to put in the&amp;nbsp;cell:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ajaxcell-non-working-version-1"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;AjaxCell: Non working version&amp;nbsp;1&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A first sketch of an &lt;tt class="docutils literal"&gt;`AjaxCell&lt;/tt&gt; component could be something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
// Careful - not working
const AjaxCell1 = ({rowIndex, col, ...props}) =&amp;gt; {
    let page = 1;
    let idx = rowIndex;
    if(rowIndex&amp;gt;=pageSize) {
        page = Math.floor(rowIndex / pageSize) + 1;
        idx = rowIndex % pageSize;
    }
    fetch('http://swapi.co/api/people/?format=json&amp;amp;page='+page).then(function(response) {
        return response.json();
    }).then(function(j) {
        // Here we have the result ! But where will it go ?
    });
    return /// what ?
}
&lt;/pre&gt;
&lt;p&gt;The col attribute will later be used to select the attribute we want to display in this cell.
The &lt;tt class="docutils literal"&gt;page&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;idx&lt;/tt&gt; will have the correct page number and idx inside that page (for example,
if &lt;tt class="docutils literal"&gt;rowIndex&lt;/tt&gt; is 33, &lt;tt class="docutils literal"&gt;page&lt;/tt&gt; will be 4 and idx will be 3. The problem with the above is that
the fetch function will be called &lt;em&gt;asynchronously&lt;/em&gt; so when the AjaxCell returns it will &lt;em&gt;not&lt;/em&gt; have
the results (yet)! So we won&amp;#8217;t be able to render anything&amp;nbsp;:(&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ajaxcell-non-working-version-2"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;AjaxCell: Non working version&amp;nbsp;2&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To be able to render &lt;em&gt;something&lt;/em&gt;, we could put the results of fetching a page to a &lt;tt class="docutils literal"&gt;cache&lt;/tt&gt; dictionary &amp;#8212; and only
fetch that page if it is not inside the &lt;tt class="docutils literal"&gt;cache&lt;/tt&gt; - if it is inside the cache then we&amp;#8217;ll just return
the correct&amp;nbsp;value:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
// Careful - not working correctly
const cache = {}
const AjaxCell2 = ({rowIndex, col, forceUpdate, ...props}) =&amp;gt; {
    let page = 1;
    let idx = rowIndex;
    if(rowIndex&amp;gt;=pageSize) {
        page = Math.floor(rowIndex / pageSize) + 1;
        idx = rowIndex % pageSize;
    }
    if (cache[page]) {
        return &amp;lt;Cell&amp;gt;{cache[page][idx][col]}&amp;lt;/Cell&amp;gt;
    } else {
        console.log(&amp;quot;Loading page &amp;quot; + page);
        fetch('http://swapi.co/api/people/?format=json&amp;amp;page='+page).then(function(response) {
            return response.json();
        }).then(function(j) {
            cache[page] = j['results'];
        });
    }
    return &amp;lt;Cell&amp;gt;-&amp;lt;/Cell&amp;gt;;
}
&lt;/pre&gt;
&lt;p&gt;The above will work, since it will return an empty (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;Cell&amp;gt;-&amp;lt;/Cell&amp;gt;&lt;/span&gt;&lt;/tt&gt;) initially but when the
&lt;tt class="docutils literal"&gt;fetch&lt;/tt&gt; returns it will set the &lt;tt class="docutils literal"&gt;cache&lt;/tt&gt; for that page and return the correct value (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;Cell&amp;gt;{cache[page][idx][col]}&amp;lt;/Cell&amp;gt;&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;However, as can be understood, when the page first loads it will call &lt;tt class="docutils literal"&gt;AjaxCell2&lt;/tt&gt; for all visible cells &amp;#8212;
because fetch is asynchronous and takes time until it returns (and sets the cache for that page), so the
&lt;tt class="docutils literal"&gt;fetch&lt;/tt&gt; will be called for &lt;em&gt;all&lt;/em&gt;&amp;nbsp;cells!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ajaxcell-non-working-version-3"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;AjaxCell: Non working version&amp;nbsp;3&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;fetch&lt;/tt&gt; ing each page multiple times is of course not acceptable, so we&amp;#8217;ll add a &lt;tt class="docutils literal"&gt;loading&lt;/tt&gt; flag
and &lt;tt class="docutils literal"&gt;fetch&lt;/tt&gt; will be called only when this flag is &lt;tt class="docutils literal"&gt;false&lt;/tt&gt;, like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
// Not ready yet
const cache = {};
let loading = false;
const AjaxCell2 = ({rowIndex, col, ...props}) =&amp;gt; {
    let page = 1;
    let idx = rowIndex;
    if(rowIndex&amp;gt;=pageSize) {
        page = Math.floor(rowIndex / pageSize) + 1;
        idx = rowIndex % pageSize;
    }
    if (cache[page]) {
        return &amp;lt;Cell&amp;gt;{cache[page][idx][col]}&amp;lt;/Cell&amp;gt;
    } else if(!loading) {
        console.log(&amp;quot;Loading page &amp;quot; + page);
        loading = true;

        fetch('http://swapi.co/api/people/?format=json&amp;amp;page='+page).then(function(response) {
            return response.json();
        }).then(function(j) {
            cache[page] = j['results'];
            loading = false;
        });
    }
    return &amp;lt;Cell&amp;gt;-&amp;lt;/Cell&amp;gt;;
}
&lt;/pre&gt;
&lt;p&gt;This works much better - the cells are rendered correctly and each page is loaded only once. However, if for example
I tried to move to the end of the table quickly, I would see some cells that are always loading (they never get their correct value). This is because
there is no way to know that the fetch function has actually completed in order to update with the latest (correct) value of that
cell and will contain the stale placeholder (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;Cell&amp;gt;-&amp;lt;/Cell&amp;gt;&lt;/span&gt;&lt;/tt&gt;)&amp;nbsp;value.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ajaxcell-final-version"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7"&gt;AjaxCell: Final&amp;nbsp;version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To clear the stale data we need to do an update to the table data
when each fetch is finished &amp;#8212; this should be done by a callback that will be passed to the &lt;tt class="docutils literal"&gt;AjaxCell&lt;/tt&gt;, like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
const cache = {};
let loading = false;
const AjaxCell = ({rowIndex, col, forceUpdate, ...props}) =&amp;gt; {
    let page = 1;
    let idx = rowIndex;
    if(rowIndex&amp;gt;=pageSize) {
        page = Math.floor(rowIndex / pageSize) + 1;
        idx = rowIndex % pageSize;
    }
    if (cache[page]) {
        return &amp;lt;Cell&amp;gt;{cache[page][idx][col]}&amp;lt;/Cell&amp;gt;
    } else if(!loading) {
        console.log(&amp;quot;Loading page &amp;quot; + page);
        loading = true;

        fetch('http://swapi.co/api/people/?format=json&amp;amp;page='+page).then(function(response) {
            return response.json();
        }).then(function(j) {
            cache[page] = j['results'];
            loading = false;
            forceUpdate();
        });
    }
    return loadingCell;
}
&lt;/pre&gt;
&lt;p&gt;So we pass a forceUpdate callback as a property which is called when a fetch is finished. This may
result to some not needed updates to the table (since we would do a fetch + forceUpdate for non-displayed
data) but we can now be positive that when the data is loaded the table will be updated to dispaly&amp;nbsp;it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-table-container-component"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id8"&gt;The Table container&amp;nbsp;component&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Finally, the component that contains the table is the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class TableContainer extends React.Component {
    render() {
        return &amp;lt;Table
            rowHeight={30} rowsCount={87} width={600} height={200} headerHeight={30}&amp;gt;

            &amp;lt;Column
              header={&amp;lt;Cell&amp;gt;Name&amp;lt;/Cell&amp;gt;}
              cell={ &amp;lt;AjaxCell col='name' forceUpdate={this.forceUpdate.bind(this)} /&amp;gt; }
              width={200}
            /&amp;gt;
            &amp;lt;Column
              header={&amp;lt;Cell&amp;gt;Birth Year&amp;lt;/Cell&amp;gt;}
              cell={ &amp;lt;AjaxCell col='birth_year' forceUpdate={this.forceUpdate.bind(this)} /&amp;gt; }
              width={200}
            /&amp;gt;
            &amp;lt;Column
              header={&amp;lt;Cell&amp;gt;Url&amp;lt;/Cell&amp;gt;}
              cell={ &amp;lt;AjaxCell col='url' forceUpdate={this.forceUpdate.bind(this)} /&amp;gt; }
              width={200}
            /&amp;gt;

        &amp;lt;/Table&amp;gt;
    }
}
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;ve made it a component in order to be able to bind the &lt;tt class="docutils literal"&gt;forceUpdate&lt;/tt&gt; method of the component to and
&lt;tt class="docutils literal"&gt;this&lt;/tt&gt; and pass it to the &lt;tt class="docutils literal"&gt;forceUpdate&lt;/tt&gt; parameter to the &lt;tt class="docutils literal"&gt;AjaxCell&lt;/tt&gt; component. I&amp;#8217;ve hard-coded
the rowsCount value &amp;#8212; instead we should have done an initial fetch to the first page of the &lt;span class="caps"&gt;API&lt;/span&gt; to get
the total number of rows and only after that fetch had returned display the &lt;tt class="docutils literal"&gt;&amp;lt;Table&amp;gt;&lt;/tt&gt; component (left
as an exercise to the&amp;nbsp;reader).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="some-enchancements"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Some&amp;nbsp;enchancements&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of displaying &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;Cell&amp;gt;-&amp;lt;/Cell&amp;gt;&lt;/span&gt;&lt;/tt&gt; (or &lt;tt class="docutils literal"&gt;&amp;lt;/Cell&amp;gt;&lt;/tt&gt;) when the page loads, I propose to define a
cell with an embedded spinner,&amp;nbsp;like&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
const loadingCell = &amp;lt;Cell&amp;gt;
    &amp;lt;img width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; alt=&amp;quot;star&amp;quot; src=&amp;quot;data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==&amp;quot; /&amp;gt;
&amp;lt;/Cell&amp;gt;
&lt;/pre&gt;
&lt;p&gt;and return this&amp;nbsp;instead.&lt;/p&gt;
&lt;p&gt;Also, if your &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; returns too fast and you&amp;#8217;d like to see what would happen if the server request took too long to return, you could
change fetch like&amp;nbsp;this&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
fetch('http://swapi.co/api/people/?format=json&amp;amp;page='+page).then(function(response) {
    return response.json();
}).then(function(j) {
    setTimeout( () =&amp;gt; {
        cache[page] = j['results'];
        loading = false;
        forceUpdate();
    }, 1000);
});
&lt;/pre&gt;
&lt;p&gt;to add a 1 second&amp;nbsp;delay.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conslusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id10"&gt;Conslusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The above is a just a proof of concept of using FixedDataTable with asynchronously loaded server-side data.
This of course could be used for small projects (I am already using it for an internal project) but I recommend
using the &lt;a class="reference external" href="http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/"&gt;flux architecture&lt;/a&gt; for more complex projects. What this more or
less means is that a store component
should be developed that will actually keep the data for each row, and a &lt;tt class="docutils literal"&gt;fetchCompleted&lt;/tt&gt; action should be
dispatched when the &lt;tt class="docutils literal"&gt;fetch&lt;/tt&gt; is finished instead of calling &lt;tt class="docutils literal"&gt;forceUpdate&lt;/tt&gt; directly.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 22 Dec 2015 15:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-12-22:2015/12/22/ajax-with-react-fixed-data-table/</guid><category>javascript</category><category>react</category><category>fixed-data-tables</category><category>FixedDataTable</category></item><item><title>PDFs in Django: The essential guide</title><link>http://spapas.github.io/2015/11/27/pdf-in-django/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id4"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-players" id="id5"&gt;The players&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#reportlab" id="id6"&gt;ReportLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#xhtml2pdf" id="id7"&gt;xhtml2pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#pypdf2" id="id8"&gt;PyPDF2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#django-integration" id="id9"&gt;Django integration&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-a-plain-old-view" id="id10"&gt;Using a plain old&amp;nbsp;view&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-a-cbv" id="id11"&gt;Using a &lt;span class="caps"&gt;CBV&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#how-does-django-xhtml2pdf-loads-resources" id="id12"&gt;How does django-xhtml2pdf loads&amp;nbsp;resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-a-common-style-for-your-pdfs" id="id13"&gt;Using a common style for your&amp;nbsp;PDFs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#changing-the-font-to-a-unicode-enabled-one" id="id14"&gt;Changing the font (to a Unicode enabled&amp;nbsp;one)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#configure-django-for-debugging-pdf-creation" id="id15"&gt;Configure Django for debugging &lt;span class="caps"&gt;PDF&lt;/span&gt;&amp;nbsp;creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#concatenating-pdfs-in-django" id="id16"&gt;Concatenating PDFs in&amp;nbsp;Django&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#more-advanced-xhtml2pdf-features" id="id17"&gt;More advanced xhtml2pdf features&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#laying-out" id="id18"&gt;Laying&amp;nbsp;out&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#extra-stuff" id="id19"&gt;Extra&amp;nbsp;stuff&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id20"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve noticed that although it is easy to create PDFs with
Python, there&amp;#8217;s no complete guide on how to
integrate these tools with Django and resolve the problems
that you&amp;#8217;ll encounter when trying to actually create PDFs
from your Django web&amp;nbsp;application.&lt;/p&gt;
&lt;p&gt;In this article I will present the solution I use for
creating PDFs with Django, along with various tips on how to
solve most of your common requirements. Specifically, here
are some things that we&amp;#8217;ll&amp;nbsp;cover:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Learn how to create PDFs &amp;quot;by&amp;nbsp;hand&amp;quot;&lt;/li&gt;
&lt;li&gt;Create PDFs with Django using a normal Djang Template (similar to an &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;page)&lt;/li&gt;
&lt;li&gt;Change the fonts of your&amp;nbsp;PDFs&lt;/li&gt;
&lt;li&gt;Use styling in your&amp;nbsp;output&lt;/li&gt;
&lt;li&gt;Create&amp;nbsp;layouts&lt;/li&gt;
&lt;li&gt;Embed images to your&amp;nbsp;PDFs&lt;/li&gt;
&lt;li&gt;Add page&amp;nbsp;numbers&lt;/li&gt;
&lt;li&gt;Merge (concatenate)&amp;nbsp;PDFs&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-players"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;The&amp;nbsp;players&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We are going to use the following main&amp;nbsp;tools:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://bitbucket.org/rptlab/reportlab"&gt;ReportLab&lt;/a&gt; is an open source python library for creating PDFs. It uses a low-level &lt;span class="caps"&gt;API&lt;/span&gt; that allows &amp;quot;drawing&amp;quot; strings on specific coordinates  on the &lt;span class="caps"&gt;PDF&lt;/span&gt; - for people familiar with creating PDFs in Java it is more or less &lt;a class="reference external" href="http://itextpdf.com/"&gt;iText&lt;/a&gt; for&amp;nbsp;python.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/chrisglass/xhtml2pdf"&gt;xhtml2pdf&lt;/a&gt; (formerly named &lt;em&gt;pisa&lt;/em&gt;) is an open source library that can convert &lt;span class="caps"&gt;HTML&lt;/span&gt;/&lt;span class="caps"&gt;CSS&lt;/span&gt; pages to &lt;span class="caps"&gt;PDF&lt;/span&gt; using&amp;nbsp;ReportLab.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/chrisglass/django-xhtml2pdf"&gt;django-xhtml2pdf&lt;/a&gt; is a wrapper around xhtml2pdf that makes integration with Django&amp;nbsp;easier.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/mstamy2/PyPDF2"&gt;PyPDF2&lt;/a&gt; is an open source tool of that can split, merge and transform pages of &lt;span class="caps"&gt;PDF&lt;/span&gt;&amp;nbsp;files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;ve created a &lt;a class="reference external" href="https://github.com/spapas/django-pdf-guide"&gt;django project&lt;/a&gt; &lt;a class="reference external" href="https://github.com/spapas/django-pdf-guide"&gt;https://github.com/spapas/django-pdf-guide&lt;/a&gt; with everything covered here. Please clone it,
install its requirements and play with it to see how everything works&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;Before integrating the above tools to a Django project, I&amp;#8217;d like to describe them individually a bit more. Any files
I mention below will be included in this&amp;nbsp;project.&lt;/p&gt;
&lt;div class="section" id="reportlab"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;ReportLab&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;ReportLab offers a really low &lt;span class="caps"&gt;API&lt;/span&gt; for creating PDFs. It is something like having a &lt;tt class="docutils literal"&gt;canvas.drawString()&lt;/tt&gt; method (for
people familiar with drawing APIs) for your &lt;span class="caps"&gt;PDF&lt;/span&gt; page. Let&amp;#8217;s take a look at an example, creating a &lt;span class="caps"&gt;PDF&lt;/span&gt; with a simple&amp;nbsp;string:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from reportlab.pdfgen import canvas
import reportlab.rl_config


if __name__ == '__main__':
    reportlab.rl_config.warnOnMissingFontGlyphs = 0
    c = canvas.Canvas(&amp;quot;./hello1.pdf&amp;quot;,)
    c.drawString(100, 100, &amp;quot;Hello World&amp;quot;)
    c.showPage()
    c.save()
&lt;/pre&gt;
&lt;p&gt;Save the above in a file named testreportlab1.py. If you run python testreportlab1.py (in an environment that has
reportlab of cours) you should see no errors and a pdf named &lt;tt class="docutils literal"&gt;hello1.pdf&lt;/tt&gt; created. If you open it in your &lt;span class="caps"&gt;PDF&lt;/span&gt;
reader you&amp;#8217;ll see a blank page with &amp;quot;Hello World&amp;quot; written in its lower right&amp;nbsp;corner.&lt;/p&gt;
&lt;p&gt;If you try to add a unicode text, for example &amp;quot;Καλημέρα ελλάδα&amp;quot;, you should see something like the&amp;nbsp;following:&lt;/p&gt;
&lt;img alt="Hello PDF" src="/images/hellopdf2.png" style="width: 280px;" /&gt;
&lt;p&gt;It seems that the default font that ReportLab uses does not have a good support for accented greek characters
since they are missing  (and probably for various other&amp;nbsp;characters).&lt;/p&gt;
&lt;p&gt;To resolve this, we could try changing the font to one that contains the missing symbols. You can find free
fonts on the internet (for example the &lt;cite&gt;DejaVu&lt;/cite&gt; font), or even grab one from your system fonts (in windows,
check out &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\windows\fonts\&lt;/span&gt;&lt;/tt&gt;). In any case, just copy the ttf file of your font inside the folder of
your project and crate a file named testreportlab2.py with the following (I am using the DejaVuSans&amp;nbsp;font):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
# -*- coding: utf-8 -*-
import reportlab.rl_config
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont


if __name__ == '__main__':
    c = canvas.Canvas(&amp;quot;./hello2.pdf&amp;quot;,)
    reportlab.rl_config.warnOnMissingFontGlyphs = 0
    pdfmetrics.registerFont(TTFont('DejaVuSans', 'DejaVuSans.ttf'))

    c.setFont('DejaVuSans', 22)
    c.drawString(100, 100, u&amp;quot;Καλημέρα ελλάδα.&amp;quot;)

    c.showPage()
    c.save()
&lt;/pre&gt;
&lt;p&gt;The above was just a scratch on the surface of ReportLab, mainly to be confident that
everything &lt;em&gt;will&lt;/em&gt; work fine for non-english speaking people! To find out more, you should check the  &lt;a class="reference external" href="http://www.reportlab.com/docs/reportlab-userguide.pdf"&gt;ReportLab open-source User Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also have to mention that
&lt;a class="reference external" href="http://reportlab.com/"&gt;the company behind ReportLab&lt;/a&gt; offers some great commercial solutions based on ReportLab for creating PDFs (similar to &lt;a class="reference external" href="http://community.jaspersoft.com/project/jasperreports-library"&gt;JasperReports&lt;/a&gt;) - check it out
if you need support or advanced&amp;nbsp;capabilities.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="xhtml2pdf"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;xhtml2pdf&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The xhtml2pdf is a really great library that allows you to use html files as a template
to a &lt;span class="caps"&gt;PDF&lt;/span&gt;. Of course, an html cannot always be converted to a &lt;span class="caps"&gt;PDF&lt;/span&gt; since,
unfortunately, PDFs &lt;em&gt;do&lt;/em&gt; have&amp;nbsp;pages.&lt;/p&gt;
&lt;p&gt;xhtml2pdf has a nice executable script that can be used to test its capabilities. After
you install it (either globally or to a virtual environment) you should be able to find
out the executable &lt;tt class="docutils literal"&gt;$&lt;span class="caps"&gt;PYTHON&lt;/span&gt;/scripts/xhtml2pdf&lt;/tt&gt; (or &lt;tt class="docutils literal"&gt;xhtml2pdf.exe&lt;/tt&gt; if you are in
Windows) and a corresponding python script &amp;#64; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;$&lt;span class="caps"&gt;PYTHON&lt;/span&gt;/scripts/xhtml2pdf-script.py&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s try to use xhtml2pdf to explore some of its capabilities. Create a file named
testxhtml2pdf.html with the following contents and run &lt;tt class="docutils literal"&gt;xhtml2pdf testxhtml2pdf.html&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Testing xhtml2pdf &amp;lt;/h1&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Hello, world!&amp;lt;/b&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Hello, italics&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;Καλημέρα Ελλάδα!&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
    &amp;lt;hr /&amp;gt;
    &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nulla erat, porttitor ut venenatis eget,
    tempor et purus. Nullam nec erat vel enim euismod auctor et at nisl. Integer posuere bibendum condimentum. Ut
    euismod velit ut porttitor condimentum. In ullamcorper nulla at lectus fermentum aliquam. Nunc elementum commodo
    dui, id pulvinar ex viverra id. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
    himenaeos.&amp;lt;/p&amp;gt;

    &amp;lt;p&amp;gt;Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed aliquam vitae lectus sit amet accumsan. Morbi
    nibh urna, condimentum nec volutpat at, lobortis sit amet odio. Etiam quis neque interdum sapien cursus ornare. Cras
    commodo lacinia sapien nec porta. Suspendisse potenti. Nulla hendrerit dolor et rutrum consectetur.&amp;lt;/p&amp;gt;
    &amp;lt;hr /&amp;gt;
    &amp;lt;img  width=&amp;quot;26&amp;quot; height=&amp;quot;20&amp;quot; src=&amp;quot;data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/
    rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0C
    cguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7&amp;quot;  &amp;gt;
    &amp;lt;hr /&amp;gt;
    &amp;lt;table&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;header0&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;header1&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;header2&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;header3&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;header4&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;header5&amp;lt;/th&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Hello World!!!&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Please notice the &lt;tt class="docutils literal"&gt;&amp;lt;meta &lt;span class="pre"&gt;http-equiv=&amp;quot;Content-Type&amp;quot;&lt;/span&gt; &lt;span class="pre"&gt;content=&amp;quot;text/html;&lt;/span&gt; &lt;span class="pre"&gt;charset=utf-8&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/tt&gt; in the above &lt;span class="caps"&gt;HTML&lt;/span&gt; &amp;#8212; also it is saved as
Unicode (Encoding - Covert to &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 in Notepad++). The result (&lt;tt class="docutils literal"&gt;testxhtml2pdf.pdf&lt;/tt&gt;) should&amp;nbsp;have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A nice header&amp;nbsp;(h1)&lt;/li&gt;
&lt;li&gt;Paragraphs&lt;/li&gt;
&lt;li&gt;Horizontal&amp;nbsp;lines&lt;/li&gt;
&lt;li&gt;No support for greek characters (same problem as with&amp;nbsp;reportlab)&lt;/li&gt;
&lt;li&gt;Images (I am inlining it as a base 64&amp;nbsp;image)&lt;/li&gt;
&lt;li&gt;A&amp;nbsp;list&lt;/li&gt;
&lt;li&gt;A&amp;nbsp;table&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before moving on, I&amp;#8217;d like to fix the problem with the greek characters. You should
set the font to one supporting greek characters, just like you did with ReportLab before.
This can be done with the help of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;font-face&lt;/span&gt;&lt;/tt&gt; &lt;a class="reference external" href="https://github.com/xhtml2pdf/xhtml2pdf/blob/master/doc/usage.rst#fonts"&gt;css directive&lt;/a&gt;. So, let&amp;#8217;s create
a file named &lt;tt class="docutils literal"&gt;testxhtml2pdf2.html&lt;/tt&gt; with the following&amp;nbsp;contents:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;

    &amp;lt;style&amp;gt;
        &amp;#64;font-face {
            font-family: DejaVuSans;
            src: url(&amp;quot;c:/progr/py/django-pdf-guide/django_pdf_guide/DejaVuSans.ttf&amp;quot;);
        }

        body {
            font-family: DejaVuSans;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Δοκιμή του xhtml2pdf &amp;lt;/h1&amp;gt;
    &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;Καλημέρα Ελλάδα!&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Before running &lt;tt class="docutils literal"&gt;xhtml2pdf testxhtml2pdf2.html&lt;/tt&gt;, please make
sure to change the url of the font file above to the absolute path of that font in your
local system . As a result, after running xhhtml2pdf
you
should see the unicode characters without&amp;nbsp;problems.&lt;/p&gt;
&lt;p&gt;I have to mention here that I wasn&amp;#8217;t able to use the font from a relative path, that&amp;#8217;s
why I used the absolute one. In case something is not right, try
running it with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; option to output debugging information (something like
&lt;tt class="docutils literal"&gt;xhtml2pdf &lt;span class="pre"&gt;-d&lt;/span&gt; testxhtml2pdf2.html&lt;/tt&gt;). You must see a line like this&amp;nbsp;one:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
DEBUG [xhtml2pdf] C:\progr\py\django-pdf-guide\venv\lib\site-packages\xhtml2pdf\context.py line 857: Load font 'c:\\progr\\py\\django-pdf-guide\\django_pdf_guide\\DejaVuSans.ttf'
&lt;/pre&gt;
&lt;p&gt;to make sure that the font is actually&amp;nbsp;loaded!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pypdf2"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;PyPDF2&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The PyPDF2 library can be used to extract pages from a &lt;span class="caps"&gt;PDF&lt;/span&gt; to a new one
or combine pages from different PDFs to a a new one. A common requirement is
to have the first and page of a report as static PDFs, create the contents
of this report through your app as a &lt;span class="caps"&gt;PDF&lt;/span&gt; and combine all three PDFs (front page,
content and back page) to the resulting &lt;span class="caps"&gt;PDF&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s see a quick example of combining two&amp;nbsp;PDFs:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import sys
from PyPDF2 import PdfFileMerger

if __name__ == '__main__':
    pdfs = sys.argv[1:]

    if not pdfs or len(pdfs) &amp;lt; 2:
        exit(&amp;quot;Please enter at least two pdfs for merging!&amp;quot;)

    merger = PdfFileMerger()

    for pdf in pdfs:
        merger.append(fileobj=open(pdf, &amp;quot;rb&amp;quot;))

    output = open(&amp;quot;output.pdf&amp;quot;, &amp;quot;wb&amp;quot;)
    merger.write(output)
&lt;/pre&gt;
&lt;p&gt;The above will try to open all input parameters (as files) and append them to a the&amp;nbsp;output.pdf.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="django-integration"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Django&amp;nbsp;integration&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To integrate the &lt;span class="caps"&gt;PDF&lt;/span&gt; creation process with django we&amp;#8217;ll use a simple app with only one model about books. We are
going to use the django-xhtml2pdf library &amp;#8212; I recommend installing the latest version (from github
using something like &lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;-e&lt;/span&gt; &lt;span class="pre"&gt;git+https://github.com/chrisglass/django-xhtml2pdf.git#egg=django-xhtml2pdf&lt;/span&gt;&lt;/tt&gt;
) since the pip package has not been updated in a long&amp;nbsp;time!&lt;/p&gt;
&lt;div class="section" id="using-a-plain-old-view"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10"&gt;Using a plain old&amp;nbsp;view&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The simplest case is to just create plain old view to display the &lt;span class="caps"&gt;PDF&lt;/span&gt;. We&amp;#8217;ll use django-xhtml2pdf along with the
followig django&amp;nbsp;template:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Books&amp;lt;/h1&amp;gt;
    &amp;lt;table&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;
        &amp;lt;/tr&amp;gt;
        {% for book in books %}
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;{{ book.id }}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ book.title }}&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        {% endfor %}
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Name it as &lt;tt class="docutils literal"&gt;books_plain_old_view.html&lt;/tt&gt; and put it on &lt;tt class="docutils literal"&gt;books/templates&lt;/tt&gt; directory. The view that
returns the above template as &lt;span class="caps"&gt;PDF&lt;/span&gt; is the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from django.http import HttpResponse
from django_xhtml2pdf.utils import generate_pdf


def books_plain_old_view(request):
    resp = HttpResponse(content_type='application/pdf')
    context = {
        'books': Book.objects.all()
    }
    result = generate_pdf('books_plain_old_view.html', file_object=resp, context=context)
    return result
&lt;/pre&gt;
&lt;p&gt;We just use the &lt;tt class="docutils literal"&gt;generate_pdf&lt;/tt&gt; method of django-xhtml2pdf to help us generate the &lt;span class="caps"&gt;PDF&lt;/span&gt;, passing it
our response object and a context dictionary (containing all&amp;nbsp;books).&lt;/p&gt;
&lt;p&gt;Instead of the simple &lt;span class="caps"&gt;HTTP&lt;/span&gt; response above, we could add a &amp;#8216;Content Disposition&amp;#8217; &lt;span class="caps"&gt;HTTP&lt;/span&gt; header to
our response
(or use the django-xhtml2pdf method &lt;tt class="docutils literal"&gt;render_to_pdf_response&lt;/tt&gt; instead of &lt;tt class="docutils literal"&gt;generate_pdf&lt;/tt&gt;)
to suggest a default filename for the file to be saved by adding the&amp;nbsp;line&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
resp['Content-Disposition'] = 'attachment; filename=&amp;quot;output.pdf&amp;quot;'
&lt;/pre&gt;
&lt;p&gt;after the definition of &lt;tt class="docutils literal"&gt;resp&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;This will have the extra effect, at least in Chrome and Firefox to show the &amp;quot;Save File&amp;quot; dialog
when clicking on the link instead of retrieving the &lt;span class="caps"&gt;PDF&lt;/span&gt; and displaying it inside* the browser&amp;nbsp;window.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-a-cbv"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11"&gt;Using a &lt;span class="caps"&gt;CBV&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t really recommend using plain old Django views - instead I propose to always use Class Based Views
for their DRYness. The best approach is to create a mixin that would allow any kind of &lt;span class="caps"&gt;CBV&lt;/span&gt; (at least any
kind of &lt;span class="caps"&gt;CBV&lt;/span&gt; that uses a template) to be rendered in &lt;span class="caps"&gt;PDF&lt;/span&gt;. Here&amp;#8217;s how we could implement a &lt;tt class="docutils literal"&gt;PdfResponseMixin&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class PdfResponseMixin(object, ):
    def render_to_response(self, context, **response_kwargs):
        context=self.get_context_data()
        template=self.get_template_names()[0]
        resp = HttpResponse(content_type='application/pdf')
        result = generate_pdf(template, file_object=resp, context=context)
        return result
&lt;/pre&gt;
&lt;p&gt;Now, we could use this mixin to create &lt;span class="caps"&gt;PDF&lt;/span&gt; outputting views from any other view! For example, here&amp;#8217;s how
we could create a book list in&amp;nbsp;pdf:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class BookPdfListView(PdfResponseMixin, ListView):
    context_object_name = 'books'
    model = Book
&lt;/pre&gt;
&lt;p&gt;To display it, you could use the same template as &lt;tt class="docutils literal"&gt;books_plain_old_view.html&lt;/tt&gt; (so either add a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;template_name='books_plain_old_view.html'&lt;/span&gt;&lt;/tt&gt;
property to the class or copy &lt;tt class="docutils literal"&gt;books_plain_old_view.html&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;books/book_list.html&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;Also, as another example, here&amp;#8217;s a &lt;tt class="docutils literal"&gt;BookPdfDetailView&lt;/tt&gt; that outputs &lt;span class="caps"&gt;PDF&lt;/span&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class BookPdfDetailView(PdfResponseMixin, DetailView):
    context_object_name = 'book'
    model = Book
&lt;/pre&gt;
&lt;p&gt;and a corresponding template (name it &lt;tt class="docutils literal"&gt;books/book_detail.html&lt;/tt&gt;):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Book Detail&amp;lt;/h1&amp;gt;
    &amp;lt;b&amp;gt;ID&amp;lt;/b&amp;gt;: {{ book.id }} &amp;lt;br /&amp;gt;
    &amp;lt;b&amp;gt;Title&amp;lt;/b&amp;gt;: {{ book.title }} &amp;lt;br /&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To add the content-disposition header and a name for your &lt;span class="caps"&gt;PDF&lt;/span&gt;, you can use the following&amp;nbsp;mixin:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class PdfResponseMixin(object, ):
    pdf_name = &amp;quot;output&amp;quot;

    def get_pdf_name(self):
        return self.pdf_name

    def render_to_response(self, context, **response_kwargs):
        context=self.get_context_data()
        template=self.get_template_names()[0]
        resp = HttpResponse(content_type='application/pdf')
        resp['Content-Disposition'] = 'attachment; filename=&amp;quot;{0}.pdf&amp;quot;'.format(self.get_pdf_name())
        result = generate_pdf(template, file_object=resp, context=context)
        return result
&lt;/pre&gt;
&lt;p&gt;You see that, in order to havea configurable output name for our &lt;span class="caps"&gt;PDF&lt;/span&gt; and be consistent with the other
django CBVs, a &lt;tt class="docutils literal"&gt;pdf_name&lt;/tt&gt; class attribute and a &lt;tt class="docutils literal"&gt;get_pdf_name&lt;/tt&gt; instance method are added. When
using the above mixin in your classes you can either provide a value for &lt;tt class="docutils literal"&gt;pdf_name&lt;/tt&gt; (to use the same for all
your instances), or override &lt;tt class="docutils literal"&gt;get_pdf_name&lt;/tt&gt; to have a dynamic&amp;nbsp;value!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-does-django-xhtml2pdf-loads-resources"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12"&gt;How does django-xhtml2pdf loads&amp;nbsp;resources&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before doing more advanced things, we need to understand how &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-xhtml2pdf&lt;/span&gt;&lt;/tt&gt; works and specifically
how we can refer to things like css, images, fonts etc from our &lt;span class="caps"&gt;PDF&lt;/span&gt; templates.
If you check the &lt;a class="reference external" href="https://github.com/chrisglass/django-xhtml2pdf/blob/master/django_xhtml2pdf/utils.py"&gt;utils.py of django-xhtml2pdf&lt;/a&gt; you&amp;#8217;ll see that it uses a function named &lt;tt class="docutils literal"&gt;fetch_resources&lt;/tt&gt;
for loading these resources. This function checks to see if the resource starts with &lt;tt class="docutils literal"&gt;/MEDIA_URL&lt;/tt&gt; or
&lt;tt class="docutils literal"&gt;/STATIC_URL&lt;/tt&gt; and converts it to a local (filesystem) path. For example, if you refer to a font like
&lt;tt class="docutils literal"&gt;/static/font1.ttf&lt;/tt&gt; in your &lt;span class="caps"&gt;PDF&lt;/span&gt; template, &lt;tt class="docutils literal"&gt;xhtml2pdf&lt;/tt&gt; will try to load the file &lt;tt class="docutils literal"&gt;STATIC_ROOT + /font1.ttf&lt;/tt&gt;
(and if it does not find the file you want to refer to there it will check all &lt;tt class="docutils literal"&gt;STATICFILES_DIRS&lt;/tt&gt; entries).&lt;/p&gt;
&lt;p&gt;Thus, you can just put your resources into your &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt; directory and use the &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt;
template tag to create &lt;span class="caps"&gt;URL&lt;/span&gt; paths for them &amp;#8212; django-xhtml2pdf will convert these to local paths and
everything will work&amp;nbsp;fine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please notice that you *need* to have configured &amp;#8220;STATIC_ROOT&amp;#8220; for this to work&lt;/strong&gt; &amp;#8212; if &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt; is
empty (and, for example you use &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; directories in your apps) then the described substitution
mechanism will &lt;em&gt;not&lt;/em&gt; work. Also, notice that the &lt;tt class="docutils literal"&gt;/static&lt;/tt&gt; directory inside your apps &lt;em&gt;cannot be used&lt;/em&gt;
for fetch resources like this
(due to how &lt;tt class="docutils literal"&gt;fetch_resources&lt;/tt&gt; is implemented it only checks if the static resource is contained inside
the &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt; or in one of the the &lt;tt class="docutils literal"&gt;STATICFILES_DIRS&lt;/tt&gt;) so be careful to either put the static files
you need to load from PDFs (fonts, styles and possibly images) to either the &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt; or the
one of the &lt;tt class="docutils literal"&gt;STATICFILES_DIRS&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-a-common-style-for-your-pdfs"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id13"&gt;Using a common style for your&amp;nbsp;PDFs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you need to create a lot of similar PDFs then you&amp;#8217;ll probably want to
use a bunch of common styles for them (same fonts, headers etc). This could be done using
the &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt; trick we saw on the previous section. However, if we include the
styling css as a static file then we won&amp;#8217;t be able to use the static-file-uri-to-local-path
mechanism described above (since the &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt; template tag won&amp;#8217;t work in static&amp;nbsp;files).&lt;/p&gt;
&lt;p&gt;Thankfully, not everything is lost &amp;#8212; Django comes to the rescue!!! We can create a single &lt;span class="caps"&gt;CSS&lt;/span&gt; file
that would be used by all our &lt;span class="caps"&gt;PDF&lt;/span&gt; templates and &lt;em&gt;include&lt;/em&gt; it in the templates using the &lt;tt class="docutils literal"&gt;{% include %}&lt;/tt&gt; Django
template tag! Django will think that this will be a normal template and paste its contents where we wanted and
also execute the templates&amp;nbsp;tags!&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll see an example of all this in the next&amp;nbsp;section.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="changing-the-font-to-a-unicode-enabled-one"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id14"&gt;Changing the font (to a Unicode enabled&amp;nbsp;one)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The time has finally arrived to change the font! It&amp;#8217;s easy if you know exactly what to do. First of all
configure your &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;STATIC_URL&lt;/tt&gt; setting, for example &lt;tt class="docutils literal"&gt;STATIC_ROOT = &lt;span class="pre"&gt;os.path.join(BASE_DIR,'static')&lt;/span&gt;&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;STATIC_URL = '/static/'&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Then, add a template-css file for your fonts in one of your templates directories. I am naming the
file &lt;tt class="docutils literal"&gt;pdfstylefonts.css&lt;/tt&gt; and I&amp;#8217;ve put it to &lt;tt class="docutils literal"&gt;books/templates&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
{% load static %}
&amp;#64;font-face {
    font-family: &amp;quot;Calibri&amp;quot;;
    src: url({% static &amp;quot;fonts/calibri.ttf&amp;quot; %});
}
&amp;#64;font-face {
    font-family: &amp;quot;Calibri&amp;quot;;
    src: url({% static &amp;quot;fonts/calibrib.ttf&amp;quot; %});
    font-weight: bold;
}
&amp;#64;font-face {
    font-family: &amp;quot;Calibri&amp;quot;;
    src: url({% static &amp;quot;fonts/calibrii.ttf&amp;quot; %});
    font-style: italic, oblique;
}
&amp;#64;font-face {
    font-family: &amp;quot;Calibri&amp;quot;;
    src: url({% static &amp;quot;fonts/calibriz.ttf&amp;quot; %});
    font-weight: bold;
    font-style: italic, oblique;
}
&lt;/pre&gt;
&lt;p&gt;I am using Calibri family of fonts (copied from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\windows\fonts&lt;/span&gt;&lt;/tt&gt;) for this &amp;#8212; I&amp;#8217;ve also configured
all styles (bold, italic, bold-italic) of this font family to use the correct ttf files. All the
ttf files have been copied to the directory &lt;tt class="docutils literal"&gt;static/fonts/&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now, add another css file that will be your global &lt;span class="caps"&gt;PDF&lt;/span&gt; styles. This should be put to the &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; directory
and could be named &lt;tt class="docutils literal"&gt;pdfstyle.css&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
h1 {
    color: blue;
}

*, html {
    font-family: &amp;quot;Calibri&amp;quot;;
    font-size:11pt;
    color: red;
}
&lt;/pre&gt;
&lt;p&gt;Next, here&amp;#8217;s a template that lists all books (and contain some greek characters &amp;#8212; the title of the books also contain
greek characters) &amp;#8212; I&amp;#8217;ve named it &lt;tt class="docutils literal"&gt;book_list_ex.html&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
{% load static %}
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
    &amp;lt;style&amp;gt;
        {% include &amp;quot;pdfstylefonts.css&amp;quot; %}
    &amp;lt;/style&amp;gt;
    &amp;lt;link rel='stylesheet' href='{% static &amp;quot;pdfstyle.css&amp;quot; %}'/&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Λίστα βιβλίων&amp;lt;/h1&amp;gt;
    &amp;lt;img src='{% static &amp;quot;pony.png&amp;quot; %}' /&amp;gt;
    &amp;lt;table&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Cover&amp;lt;/th&amp;gt;
        &amp;lt;/tr&amp;gt;
        {% for book in books %}
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;{{ book.id }}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ book.title }}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;img src='{{ book.cover.url }}' /&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        {% endfor %}
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll see that the &lt;tt class="docutils literal"&gt;pdfstylefonts.css&lt;/tt&gt; is included as a Django template (so that &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt; will
work in that file) while &lt;tt class="docutils literal"&gt;pdfstyle.css&lt;/tt&gt; is included using &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt;.
Als, notice that I&amp;#8217;ve also added a static image (using the &lt;tt class="docutils literal"&gt;{% static %}&lt;/tt&gt; tag) and a dynamic (media)
file to show off how great the url-to-local-path mechanism works. Please notice that for the
media files to work fine in your development environment you need to configure the
&lt;tt class="docutils literal"&gt;MEDIA_URL&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;MEDIA_ROOT&lt;/tt&gt; settigns (similar to &lt;tt class="docutils literal"&gt;STATIC_URL&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;STATIC_ROOT&lt;/tt&gt;) and follow the
&lt;a class="reference external" href="https://docs.djangoproject.com/en/1.8/howto/static-files/#serving-files-uploaded-by-a-user-during-development"&gt;serve files uploaded by a user during development&lt;/a&gt; tutorial on Django&amp;nbsp;docs.&lt;/p&gt;
&lt;p&gt;Finally, if you configure a PdfResponseMixin ListView like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class BookExPdfListView(PdfResponseMixin, ListView):
    context_object_name = 'books'
    model = Book
    template_name = 'books/book_list_ex.html'
&lt;/pre&gt;
&lt;p&gt;you should see be able to see the correct (calibri) font (defined in &lt;tt class="docutils literal"&gt;pdfstylefonts.css&lt;/tt&gt;), with unicode characters without problems
including both the static and user uploaded images and with the styles defined in the pdf stylesheet (&lt;tt class="docutils literal"&gt;pdfstyle.css&lt;/tt&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="configure-django-for-debugging-pdf-creation"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15"&gt;Configure Django for debugging &lt;span class="caps"&gt;PDF&lt;/span&gt;&amp;nbsp;creation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you experience any problems, you can configure xhtml2pdf to output &lt;span class="caps"&gt;DEBUG&lt;/span&gt; information. To do this,
you may change your django logging configuration like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'xhtml2pdf': {
            'handlers': ['console'],
            'level': 'DEBUG',
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;This configuration will keep existing loggers (&lt;tt class="docutils literal"&gt;'disable_existing_loggers': False,&lt;/tt&gt;) and will configure
&lt;tt class="docutils literal"&gt;xhtml2pdf&lt;/tt&gt; to log its output to the console, helping us find out why some things won&amp;#8217;t be&amp;nbsp;working.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="concatenating-pdfs-in-django"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16"&gt;Concatenating PDFs in&amp;nbsp;Django&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The final section of the &lt;span class="caps"&gt;PDF&lt;/span&gt;-Django-integration is to explain how we can concatenate PDFs in django using PyPDF2. There may be
some other requirements like extracting pages from PDFs however the most common one as explained before is to just append
the pages of one &lt;span class="caps"&gt;PDF&lt;/span&gt; after the other &amp;#8212; after all using PyPDF2 is really easy after you get the hang of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;To be more &lt;span class="caps"&gt;DRY&lt;/span&gt;, I will create a &lt;tt class="docutils literal"&gt;CoverPdfResponseMixin&lt;/tt&gt; that will output a &lt;span class="caps"&gt;PDF&lt;/span&gt; &lt;em&gt;with&lt;/em&gt; a cover. To be &lt;em&gt;even more&lt;/em&gt; &lt;span class="caps"&gt;DRY&lt;/span&gt;,
I will refactor &lt;tt class="docutils literal"&gt;PdfResponseMixin&lt;/tt&gt; to put some common code in an extra method so that &lt;tt class="docutils literal"&gt;CoverPdfResponseMixin&lt;/tt&gt; could inherit from&amp;nbsp;it:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class PdfResponseMixin(object, ):
    def write_pdf(self, file_object, ):
        context = self.get_context_data()
        template = self.get_template_names()[0]
        generate_pdf(template, file_object=file_object, context=context)

    def render_to_response(self, context, **response_kwargs):
        resp = HttpResponse(content_type='application/pdf')
        self.write_pdf(resp)
        return resp


class CoverPdfResponseMixin(PdfResponseMixin, ):
    cover_pdf = None

    def render_to_response(self, context, **response_kwargs):
        merger = PdfFileMerger()
        merger.append(open(self.cover_pdf, &amp;quot;rb&amp;quot;))

        pdf_fo = StringIO.StringIO()
        self.write_pdf(pdf_fo)
        merger.append(pdf_fo)

        resp = HttpResponse(content_type='application/pdf')
        merger.write(resp)
        return resp
&lt;/pre&gt;
&lt;p&gt;So, &lt;tt class="docutils literal"&gt;PdfResponseMixin&lt;/tt&gt; now has a &lt;tt class="docutils literal"&gt;write_pdf&lt;/tt&gt; method that gets a file-like object and outputs the &lt;span class="caps"&gt;PDF&lt;/span&gt; there.
The new mixin, &lt;tt class="docutils literal"&gt;CoverPdfResponseMixin&lt;/tt&gt; has a &lt;tt class="docutils literal"&gt;cover_pdf&lt;/tt&gt; attribute that should be configured with the filesystem
path of the cover file. The &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method now will create a &lt;tt class="docutils literal"&gt;PdfFileMerger&lt;/tt&gt; (which is empty
initially) to which it appends the contents &lt;tt class="docutils literal"&gt;cover_pdf&lt;/tt&gt;. After that, it creates a file-stream (using StreamIO)
and uses &lt;tt class="docutils literal"&gt;write_pdf&lt;/tt&gt; to create the &lt;span class="caps"&gt;PDF&lt;/span&gt; there and appends that file-stream to the merger. Finally, it writes
the merger contents to the &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;One thing that I&amp;#8217;ve seen is that if you want to concatenate many PDFs with many pages sometimes you&amp;#8217;ll get
a strange an error when using &lt;tt class="docutils literal"&gt;PdfFileMerger&lt;/tt&gt;. I was able to overcome this by reading and appending the pages of each
&lt;span class="caps"&gt;PDF&lt;/span&gt; to-be-appended one by one using the &lt;tt class="docutils literal"&gt;PdfFileReader&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;PdfFileWriter&lt;/tt&gt; objects. Here&amp;#8217;s a small snippet of how
this could be&amp;nbsp;done:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
pdfs = [] # List of pdfs to be concatenated
writer = PdfFileWriter()

for pdf in pdfs:
    reader = PdfFileReader(open(pdf, &amp;quot;rb&amp;quot;))
    for i in range(reader.getNumPages()):
        writer.addPage(reader.getPage(i))

resp = HttpResponse(content_type='application/pdf')
writer.write(resp)
return resp
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="more-advanced-xhtml2pdf-features"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id17"&gt;More advanced xhtml2pdf&amp;nbsp;features&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this section I will present some information on how to use various xhtml2pdf features
to create the most common required printed document features, for example adding page
numbers, adding headers and footers&amp;nbsp;etc.&lt;/p&gt;
&lt;div class="section" id="laying-out"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18"&gt;Laying&amp;nbsp;out&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To find out how you can create your pages you should read the
&lt;a class="reference external" href="https://github.com/xhtml2pdf/xhtml2pdf/blob/master/doc/usage.rst#defining-page-layouts"&gt;defining page layouts&lt;/a&gt; section of the xhtml2pdf manual. There
you&amp;#8217;ll see that the basic components of laying out in xhtml2pdf is
&amp;#64;page to create pages and &amp;#64;frames to create rectangular components
inside these pages. So each page will have a number of frames
inside it. These frames are seperated to static and dynamic. Staticsome
should be used for things like headers
and footers (so they&amp;#8217;ll be the same across all pages) and dynamic will
contain the main content of the&amp;nbsp;report.&lt;/p&gt;
&lt;p&gt;For pages you can use any page size you want, not just the specified ones. For example, in one of my
projects I wanted to create a &lt;span class="caps"&gt;PDF&lt;/span&gt; print on a normal plastic card, so I&amp;#8217;d used the
following &lt;tt class="docutils literal"&gt;size: 8.56cm 5.398cm;&lt;/tt&gt;. Also, page templates can be named
and you can use different ones in the same &lt;span class="caps"&gt;PDF&lt;/span&gt; (so you could create
a cover page with a different page template, use it first and then continue
with the normal pages). To name a tempalte you just use &amp;#64;page template_name {}
and to change the template use the combination of the following two xhtml2pdf&amp;nbsp;tags:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;pdf:nexttemplate name=&amp;quot;back_page&amp;quot; /&amp;gt;
&amp;lt;pdf:nextpage /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now, one thing I&amp;#8217;ve noticed is that you are not able to use a named template for the first
page of your &lt;span class="caps"&gt;PDF&lt;/span&gt;. So, what I&amp;#8217;ve done is that I create an anonymous (default) page for the
first page of the report. If I want to &lt;em&gt;reuse&lt;/em&gt; it in another page, I copy it and name it
accordingly. I will give an example&amp;nbsp;shortly.&lt;/p&gt;
&lt;p&gt;Now, for frames, I recommend using the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-pdf-frame-border:&lt;/span&gt; 1;&lt;/tt&gt; command for debugging where
they are actually printed. Also, I recommend using a normal ruler and measuring completely
where you want them to be. For example, for the following&amp;nbsp;frame:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;frame photo_frame {
        -pdf-frame-border: 1;
        top:  2.4cm;
        left: 6.2cm;
        width: 1.9cm;
        height: 2.2cm;
}
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;d used a ruler to find out that I want it to start 2.4 cm from the top of my page (actually a credit card)
and 6.2 cm from the left and have a width and height of 1.9 and 2.2&amp;nbsp;cm.&lt;/p&gt;
&lt;p&gt;I recommend naming all frames to be able to distinguish them however I don&amp;#8217;t think that their name plays
any other role. However, for static frames you must define the id of the content they will contain using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-pdf-frame-content&lt;/span&gt;&lt;/tt&gt;
in the css and a div with the corresponding id in the &lt;span class="caps"&gt;PDF&lt;/span&gt; template. For example, you could define a frame header like&amp;nbsp;this&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;frame header {
  -pdf-frame-content: headerContent;
  width: 8in;
  top: 0.5cm;
  margin-left: 0.5cm;
  margin-right: 0.5cm;
  height: 2cm;
}
&lt;/pre&gt;
&lt;p&gt;and its content like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;div id='headerContent'&amp;gt;
  &amp;lt;h1 &amp;gt;
    Header !
  &amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Please notice that if for some reason the stuff you want to put in your static frames does not fit there the frame will
be totally empty. This means that if you have size for three lines but you want to output five lines in a static frame
then you&amp;#8217;ll see no&amp;nbsp;lines!&lt;/p&gt;
&lt;p&gt;Now, for dynamic content you can expect the opposite behavior:
You &lt;em&gt;cannot&lt;/em&gt; select to which dynamic frame your content goes, instead the content just just flows to the first dynamic frame it
fits! If it does not fit in any dynamic frames in the current page then a new page will be&amp;nbsp;created.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d like to present a full example here on the already mentioned project of printing a plastic card for the books. I had two page layouts,
one for the front page having a frame with the owner&amp;#8217;s data and another frame with his photo and one for the back page having
a barcode. This is a Django template that is used to print not only but a &lt;span class="caps"&gt;PDF&lt;/span&gt; with a group of these&amp;nbsp;cards:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
&amp;lt;style&amp;gt;
    {% include &amp;quot;pdfstylefonts.css&amp;quot; %}
&amp;lt;/style&amp;gt;
&amp;lt;style type='text/css'&amp;gt;
    &amp;#64;page {
        size: 8.56cm 5.398cm;
        margin: 0.0cm 0.0cm 0.0cm 0.0cm;
        padding: 0;

        &amp;#64;frame table_frame {
            /* -pdf-frame-border: 1; */
            top:  2.4cm;
            left: 0.4cm;
            width: 5.5cm;
            height: 3cm;
        }

        &amp;#64;frame photo_frame {
            /* -pdf-frame-border: 1; */
            top:  2.4cm;
            left: 6.2cm;
            width: 1.9cm;
            height: 2.2cm;
        }
    }

    &amp;#64;page front_page {
        size: 8.56cm 5.398cm;
        margin: 0.0cm 0.0cm 0.0cm 0.0cm;
        padding: 0;

        &amp;#64;frame table_frame {
            /* -pdf-frame-border: 1; */
            top:  2.4cm;
            left: 0.4cm;
            width: 5.5cm;
            height: 3cm;
        }

        &amp;#64;frame photo_frame {
            /* -pdf-frame-border: 1; */
            top:  2.4cm;
            left: 6.2cm;
            width: 1.9cm;
            height: 2.2cm;
        }
    }

    &amp;#64;page back_page {
        size: 8.56cm 5.398cm;
        margin: 0.0cm 0.0cm 0.0cm 0.0cm;
        padding: 0;

        &amp;#64;frame barcode_frame {
            /* -pdf-frame-border: 1; */
            top:  3.9cm;
            left: 1.8cm;
            width: 4.9cm;
            height: 1.1cm;
        }
    }

    *, html {
        font-family: &amp;quot;Calibri&amp;quot;;
        font-size: 8pt;
        line-height: 80%;
    }

    .bigger {
        font-size:9pt;
        font-weight: bold;
    }
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    {% for book in books %}
        &amp;lt;div&amp;gt;
            &amp;lt;! -- Here I print the card data. It fits exactly in the table_frame so ... -&amp;gt;
            {{ book.title }}&amp;lt;br /&amp;gt;
            Data line 2&amp;lt;br /&amp;gt;
            Data line 3&amp;lt;br /&amp;gt;
            Data line 4&amp;lt;br /&amp;gt;
            Data line 5&amp;lt;br /&amp;gt;
            Data line 6&amp;lt;br /&amp;gt;
            Data line 7&amp;lt;br /&amp;gt;
            Data line 8&amp;lt;br /&amp;gt;
            Data line 9&amp;lt;br /&amp;gt;
            Data line 10&amp;lt;br /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;
            &amp;lt;! -- This photo here will be outputted to the photo_frame --&amp;gt;
            &amp;lt;img src='{{ book.cover.url }}' style='width:1.9cm ; height: 2.2cm ; ' /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;! -- Now the template is chaned to print the back of the card --&amp;gt;
        &amp;lt;pdf:nexttemplate name=&amp;quot;back_page&amp;quot; /&amp;gt;
        &amp;lt;pdf:nextpage /&amp;gt;

        &amp;lt;div &amp;gt;
            &amp;lt;center&amp;gt;
                &amp;lt;! -- Print the barcode to the barcode_frame --&amp;gt;
                &amp;lt;pdf:barcode value=&amp;quot;{{ book.id }}&amp;quot; type=&amp;quot;code128&amp;quot; humanreadable=&amp;quot;1&amp;quot; barwidth=&amp;quot;0.43mm&amp;quot; barheight=&amp;quot;0.6cm&amp;quot; align=&amp;quot;middle&amp;quot; /&amp;gt;
            &amp;lt;/center&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- Use the front_page template again for the next card --&amp;gt;
        &amp;lt;pdf:nexttemplate name=&amp;quot;front_page&amp;quot; /&amp;gt;
        &amp;lt;pdf:nextpage /&amp;gt;
    {% endfor %}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice that I want to print exactly 10 lines in the &lt;tt class="docutils literal"&gt;table_frame&lt;/tt&gt; (that&amp;#8217;s why I use &amp;lt;br /&amp;gt; to go to next line) &amp;#8212; if I had printed
3-4 lines (for example) then the photo &lt;em&gt;would fit&lt;/em&gt; in the &lt;tt class="docutils literal"&gt;table_frame&lt;/tt&gt; and would be printed there and &lt;em&gt;not&lt;/em&gt; in the &lt;tt class="docutils literal"&gt;photo_frame&lt;/tt&gt;! Also,
another interesting thing is that if I had
outputed 8-9 lines then the photo wouldn&amp;#8217;t fit in that small space and would also be printed to the &lt;tt class="docutils literal"&gt;photo_frame&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="extra-stuff"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id19"&gt;Extra&amp;nbsp;stuff&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Some extra things I want to mention concerning&amp;nbsp;xhtml2pdf:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&amp;lt;pdf:pagenumber&amp;gt;&lt;/tt&gt; to output the current page number (please end the line after this&amp;nbsp;tag)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&amp;lt;pdf:pagecount&amp;gt;&lt;/tt&gt; to output the total page number (please end the line after this&amp;nbsp;tag)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if you want to print a footer with the pages, I recommend something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;div id='footerContent'&amp;gt;
  Page &amp;lt;pdf:pagenumber&amp;gt;
  from &amp;lt;pdf:pagecount&amp;gt;
  total
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice how the lines end after the&amp;nbsp;tags.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&amp;lt;pdf:barcode&amp;gt;&lt;/tt&gt;: Output a barcode in your &lt;span class="caps"&gt;PDF&lt;/span&gt;. Here are the possible barcode types: I2of5, Standard39, Extended39, Standard93, Extended93, &lt;span class="caps"&gt;MSI&lt;/span&gt;, Codabar, Code11, &lt;span class="caps"&gt;FIM&lt;/span&gt;, &lt;span class="caps"&gt;POSTNET&lt;/span&gt;, USPS_4State, Code128, &lt;span class="caps"&gt;EAN13&lt;/span&gt;, &lt;span class="caps"&gt;EAN8&lt;/span&gt;, &lt;span class="caps"&gt;QR&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;You may add a page background image using  the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;background-image&lt;/span&gt;&lt;/tt&gt; property of &lt;tt class="docutils literal"&gt;&amp;#64;page&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, if you want the templates you create from your development/&lt;span class="caps"&gt;UAT&lt;/span&gt; systems to be different
than the production ones you could do something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;page {
    {% if DEBUG %}
        background-image: url({% static &amp;quot;debug.png&amp;quot; %});
    {% endif %}
    &amp;lt;!-- Other page properties --&amp;gt;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id20"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I hope that using the techniques described in this essential guide you&amp;#8217;ll
be able to create great looking &lt;span class="caps"&gt;PDF&lt;/span&gt; documents from your Django application
and overcome any difficulties that may arise. If you feel that there&amp;#8217;s something
I&amp;#8217;ve not covered properly (and is not covered by the documentation) please comment
out and I&amp;#8217;ll be happy to research it a bit and update the article with&amp;nbsp;info.&lt;/p&gt;
&lt;p&gt;I am using all the above in various production applications for a long time and everything
is smooth so don&amp;#8217;t afraid to create PDFs from&amp;nbsp;Django!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Fri, 27 Nov 2015 10:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-11-27:2015/11/27/pdf-in-django/</guid><category>pdf</category><category>django</category><category>reportlab</category><category>python</category><category>xhtml2pdf</category></item><item><title>Improve your client-side-javascript workflow more by using ES6</title><link>http://spapas.github.io/2015/11/16/using-browserify-es6/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#npm-save-save-dev-and-avoiding-global-deps" id="id2"&gt;&lt;span class="caps"&gt;NPM&lt;/span&gt;, &amp;#8212;save, &amp;#8212;save-dev and avoiding global&amp;nbsp;deps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-babel" id="id3"&gt;Using&amp;nbsp;babel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#integrate-babel-with-browserify" id="id4"&gt;Integrate babel with&amp;nbsp;browserify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-object-spread-operator" id="id5"&gt;The object-spread&amp;nbsp;operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id6"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update 22/12/2015:&lt;/strong&gt; Add section for the object-spread&amp;nbsp;operator.&lt;/p&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In a &lt;a class="reference external" href="http://spapas.github.io/2015/05/27/using-browserify-watchify/"&gt;previous article&lt;/a&gt;
we presented a simple workflow to improve your client-side (javascript) workflow
by including a bunch of tools from the node-js world i.e &lt;a class="reference external" href="http://browserify.org/"&gt;browserify&lt;/a&gt; and
its friends, &lt;a class="reference external" href="https://github.com/substack/watchify"&gt;watchify&lt;/a&gt; and &lt;a class="reference external" href="https://www.npmjs.com/package/uglify-js"&gt;uglify-js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using these tools we were able to properly manage our client side dependencies
(no more script tags in our html templates) and modularize our code
(so we could avoid monolithic javascript files that contained all our code).
Another great improvement to our workflow would be to include &lt;span class="caps"&gt;ES6&lt;/span&gt; to the&amp;nbsp;mix!&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;ES6&lt;/span&gt; (or EcmaScript 2015) is more or less &amp;quot;Javascript: &lt;span class="caps"&gt;TNG&lt;/span&gt;&amp;quot;. It has many features
that greatly improve the readability and writability of javascript code - for instance,
thick arrows, better classes, better modules, iterators/generators, template strings,
default function parameters and many others!
More info on these features and how they could be used can be found on the &lt;a class="reference external" href="https://github.com/lukehoban/es6features"&gt;es6features&lt;/a&gt;&amp;nbsp;repository.&lt;/p&gt;
&lt;p&gt;Unfortunately, these features are either not supported at all, or they are partially supported
on current (November 2015) browsers. However all is &lt;em&gt;not&lt;/em&gt; lost yet: Since we already use browserify
to our client side workflow, we can easily enable it to read source files with &lt;span class="caps"&gt;ES6&lt;/span&gt; syntax
and transform them to normal javascript using a transformation through the &lt;a class="reference external" href="https://babeljs.io/"&gt;babel&lt;/a&gt;&amp;nbsp;tool.&lt;/p&gt;
&lt;p&gt;In the following, we&amp;#8217;ll talk a bit more about the node-js package manager (npm) features,
talk a little about babel and finally
modify our workflow so that it will be able to use &lt;span class="caps"&gt;ES6&lt;/span&gt;! Please notice that to properly follow this article
you need to first read the &lt;a class="reference external" href="http://spapas.github.io/2015/05/27/using-browserify-watchify/"&gt;previous one&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="npm-save-save-dev-and-avoiding-global-deps"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;&lt;span class="caps"&gt;NPM&lt;/span&gt;, &amp;#8212;save, &amp;#8212;save-dev and avoiding global&amp;nbsp;deps&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the previous article, I had recommended to install the needed tools
(needed to create the output bundle browserify, watchify, uglify) globally
using npm install -g package (of course the normal dependencies like moment.js
would be installed locally).
This has one advantage and two disadvantages: It
puts these tools to the path so they can be called immediately (i.e browserify)
but you will need root access to install a package globally and nothing is
saved on &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; so you don&amp;#8217;t know which packages must be installed
in order to start developing the&amp;nbsp;project!&lt;/p&gt;
&lt;p&gt;This could be ok for the introductionary article, however for this one I
will propose another alternative: Install all the tools &lt;em&gt;locally&lt;/em&gt; using just
&lt;tt class="docutils literal"&gt;npm install package &lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt;. These tools will be put to the &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; folder. They
&lt;em&gt;will not&lt;/em&gt; be put to the path, but if you want to execute a binary by yourself
to debug the output, you can find it in &lt;tt class="docutils literal"&gt;node_modules/bin&lt;/tt&gt;, for example,
for browserify you can run &lt;tt class="docutils literal"&gt;node_modules/bin/browserify&lt;/tt&gt;. Another intersting
thing is that if you create executable scripts in your &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; you
don&amp;#8217;t actually need to include the full path but the binaries will be&amp;nbsp;found.&lt;/p&gt;
&lt;p&gt;Another thing I&amp;#8217;d like to discuss here is the difference between &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save-dev&lt;/span&gt;&lt;/tt&gt; options that can be passed to npm install. If you take
a look at other guides you&amp;#8217;ll see that people are using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save-dev&lt;/span&gt;&lt;/tt&gt; for
development dependencies (i.e testing) and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt; for normal dependencies.
The difference is that these dependencies are saved in different places in
&lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; and if you run &lt;tt class="docutils literal"&gt;npm install &lt;span class="pre"&gt;--production&lt;/span&gt;&lt;/tt&gt; you&amp;#8217;ll get only
the normal dependencies (while, if you run &lt;tt class="docutils literal"&gt;npm install&lt;/tt&gt; all dependencies
will be installed). In these articles, I chose to just use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt; everywhere,
after all the only thing that would be needed for production would be the
&lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt; output&amp;nbsp;file.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-babel"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Using&amp;nbsp;babel&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://babeljs.io/"&gt;babel&lt;/a&gt; library &amp;quot;is a JavaScript compiler&amp;quot;. It gets input files in a variant
of javascript (for example, &lt;span class="caps"&gt;ES6&lt;/span&gt;) and produces normal javascript files &amp;#8212; something
like what browserify transforms do. However, what babel does (and I think its
the only tool that does this) is that it allows you to use &lt;span class="caps"&gt;ES6&lt;/span&gt; features &lt;em&gt;now&lt;/em&gt; by
transpiling them to normal (&lt;span class="caps"&gt;ES5&lt;/span&gt;) javascript. Also, babel has &lt;a class="reference external" href="https://babeljs.io/docs/plugins/"&gt;various other transforms&lt;/a&gt;,
including a react transform
(so you can use this instead of the reactify&amp;nbsp;browserify-transform)!&lt;/p&gt;
&lt;p&gt;In any case, to be able to use &lt;span class="caps"&gt;ES6&lt;/span&gt;, we&amp;#8217;ll need to install babel and its es6 presets
(don&amp;#8217;t forget that you need to have a &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; for the dependencies to be
saved so either do an &lt;tt class="docutils literal"&gt;npm init&lt;/tt&gt; or create a &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; file containing only
&lt;tt class="docutils literal"&gt;{}&lt;/tt&gt;):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install  babel babel-preset-es2015 --save
&lt;/pre&gt;
&lt;p&gt;If we wanted to also use babel for react we&amp;#8217;d need to install&amp;nbsp;babel-preset-react.&lt;/p&gt;
&lt;p&gt;To configure babel we can either add a &lt;tt class="docutils literal"&gt;babel&lt;/tt&gt;
section in our &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; or create a new file named .babelrc and put the configuration&amp;nbsp;there.&lt;/p&gt;
&lt;p&gt;I prefer the first one since we are already using the &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt;. So add the following attribute
to your &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;quot;babel&amp;quot;: {
  &amp;quot;presets&amp;quot;: [
    &amp;quot;es2015&amp;quot;
  ]
}
&lt;/pre&gt;
&lt;p&gt;If you wanted to configure it through &lt;tt class="docutils literal"&gt;.babelrc&lt;/tt&gt; then you&amp;#8217;d just copy to it the contents of &lt;tt class="docutils literal"&gt;&amp;quot;babel&amp;quot;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;To do some tests with babel, you can install its cli (it&amp;#8217;s not included in the babel package) through
&lt;tt class="docutils literal"&gt;npm install &lt;span class="pre"&gt;babel-cli&lt;/span&gt;&lt;/tt&gt;. Now, you can run &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;node_modules/.bin/babel&lt;/span&gt;&lt;/tt&gt;. For example, create a
file named &lt;tt class="docutils literal"&gt;testbabel.js&lt;/tt&gt; with the following contents (thick&amp;nbsp;arrow):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
[1,2,3].forEach(x =&amp;gt; console.log(x) );
&lt;/pre&gt;
&lt;p&gt;when you pass it to babel you&amp;#8217;ll see the following&amp;nbsp;output:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt;node_modules\.bin\babel testbabel.js
&amp;quot;use strict&amp;quot;;

[1, 2, 3].forEach(function (x) {
  return console.log(x);
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="integrate-babel-with-browserify"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Integrate babel with&amp;nbsp;browserify&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To call babel from browserify we&amp;#8217;re going to use the &lt;a class="reference external" href="https://github.com/babel/babelify"&gt;babelify&lt;/a&gt; browserify transform which
actually uses babel to transpile the browserify input. After installing it&amp;nbsp;with&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install babelify --save
&lt;/pre&gt;
&lt;p&gt;you need to tell browserify to use it. To do this, you&amp;#8217;ll just pass a -t babelify parameter to
browserify. So if you run it with the &lt;tt class="docutils literal"&gt;testbabel.js&lt;/tt&gt; file as input you&amp;#8217;ll see the following&amp;nbsp;output:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt;node_modules\.bin\browserify -t babelify testbabel.js
[...] browserify gibberish
&amp;quot;use strict&amp;quot;;

[1, 2, 3].forEach(function (x) {
  return console.log(x);
});

[...] more browserify gibberish
&lt;/pre&gt;
&lt;p&gt;yey &amp;#8212; the code is transpiled to &lt;span class="caps"&gt;ES5&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;To create a complete project, let&amp;#8217;s add a normal requirement&amp;nbsp;(moment.js):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install moment --save
&lt;/pre&gt;
&lt;p&gt;and a file named &lt;tt class="docutils literal"&gt;src\main.js&lt;/tt&gt; that uses it with &lt;span class="caps"&gt;ES6&lt;/span&gt;&amp;nbsp;syntax:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import moment from 'moment';

const arr = [1,2,3,4,5];
arr.forEach(x =&amp;gt; setTimeout(() =&amp;gt; console.log(`Now: ${moment().format(&amp;quot;HH:mm:ss&amp;quot;)}, Later: ${moment().add(x, &amp;quot;days&amp;quot;).format(&amp;quot;L&amp;quot;)}...`), x*1000));
&lt;/pre&gt;
&lt;p&gt;To create the output javascript file, we&amp;#8217;ll use the browserify and watchify commands with the
addition of the -t babelify switch. Here&amp;#8217;s the complete &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; for this&amp;nbsp;project:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
{
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;babel&amp;quot;: &amp;quot;^6.1.18&amp;quot;,
    &amp;quot;babel-preset-es2015&amp;quot;: &amp;quot;^6.1.18&amp;quot;,
    &amp;quot;babelify&amp;quot;: &amp;quot;^7.2.0&amp;quot;,
    &amp;quot;browserify&amp;quot;: &amp;quot;^12.0.1&amp;quot;,
    &amp;quot;moment&amp;quot;: &amp;quot;^2.10.6&amp;quot;,
    &amp;quot;uglify-js&amp;quot;: &amp;quot;^2.6.0&amp;quot;,
    &amp;quot;watchify&amp;quot;: &amp;quot;^3.6.1&amp;quot;
  },
  &amp;quot;scripts&amp;quot;: {
    &amp;quot;watch&amp;quot;: &amp;quot;watchify src/main.js -o dist/bundle.js -v -t babelify&amp;quot;,
    &amp;quot;build&amp;quot;: &amp;quot;browserify src/main.js -t babelify | uglifyjs -mc warnings=false &amp;gt; dist/bundle.js&amp;quot;
  },
  &amp;quot;babel&amp;quot;: {
    &amp;quot;presets&amp;quot;: [
      &amp;quot;es2015&amp;quot;
    ]
  }
}
&lt;/pre&gt;
&lt;p&gt;Running &lt;tt class="docutils literal"&gt;npm run build&lt;/tt&gt; should create a &lt;tt class="docutils literal"&gt;dist/bundle.js&lt;/tt&gt; file. If you include this in an html,
you should see something like this in the&amp;nbsp;console:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
Now: 13:52:09, Later: 11/17/2015...
Now: 13:52:10, Later: 11/18/2015...
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="the-object-spread-operator"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;The object-spread&amp;nbsp;operator&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Many examples in the internet use the &lt;a class="reference external" href="https://facebook.github.io/react/docs/jsx-spread.html#spread-attributes"&gt;object spread operator&lt;/a&gt; which is &lt;a class="reference external" href="http://stackoverflow.com/questions/31115276/ecmascript-6-spread-operator-in-object-deconstruction-support-in-typescript-and"&gt;not part of es6&lt;/a&gt; so our
proposed babel configuration does not support it!
To be able to use this syntax, we&amp;#8217;ll need to install the corresponding babel plugin by using
&lt;tt class="docutils literal"&gt;npm install &lt;span class="pre"&gt;babel-plugin-transform-object-rest-spread&lt;/span&gt; &lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt; and add it to our babel configuration
in the plugins section, something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;quot;presets&amp;quot;: [
  &amp;quot;es2015&amp;quot;,
  &amp;quot;react&amp;quot;
],
&amp;quot;plugins&amp;quot;: [
  &amp;quot;transform-object-rest-spread&amp;quot;
]
&lt;/pre&gt;
&lt;p&gt;If everything is ok this should be transpiled without errors using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;node_modules\.bin\browserify&lt;/span&gt; testbabe.js &lt;span class="pre"&gt;-t&lt;/span&gt; babelify&lt;/tt&gt;&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
let x = {a:1 , b:2 };
let y = {...x, c: 3};
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the combination of babel and javascript we can easily write &lt;span class="caps"&gt;ES6&lt;/span&gt; code in our modules! This,
along with the modularization of our code and the management of client-side dependencies should
make client side development a&amp;nbsp;breeze!&lt;/p&gt;
&lt;p&gt;Please notice that to keep the presented workflow simple and easy to
replicate and configure, we have not used any external
task runners (like gulp or grunt) &amp;#8212; all configuration is kept in a single file (package.json) and
the whole environment can be replicated just by doing a &lt;tt class="docutils literal"&gt;npm install&lt;/tt&gt;. Of course, the capabilities of
browserify are not unlimited, so if you wanted to do something more complicated
(for instance, lint your code before passing it to browserify) you&amp;#8217;d need to use the mentioned
task runners (or webpack which is the current trend in javascript bundlers and actually replaces
the task&amp;nbsp;runners).&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 16 Nov 2015 14:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-11-16:2015/11/16/using-browserify-es6/</guid><category>javascript</category><category>browserify</category><category>node</category><category>npm</category><category>watchify</category><category>generic</category><category>uglify</category><category>babel</category><category>es6</category></item><item><title>Django dynamic tables and filters for similar models</title><link>http://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-problem-we-ll-solve" id="id2"&gt;The problem we&amp;#8217;ll&amp;nbsp;solve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-the-dynamic-table" id="id3"&gt;Adding the dynamic&amp;nbsp;table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-a-dynamic-form-for-filtering" id="id4"&gt;Creating a dynamic form for&amp;nbsp;filtering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-the-dynamic-cbv" id="id5"&gt;Creating the dynamic &lt;span class="caps"&gt;CBV&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id6"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of my favorite django apps is &lt;a class="reference external" href="https://github.com/bradleyayers/django-tables2"&gt;django-tables2&lt;/a&gt;: It allows you to
easily create pagination and sorting enabled &lt;span class="caps"&gt;HTML&lt;/span&gt; tables to represent
your model data using the usual djangonic technique (similar to how
you &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#modelform"&gt;create ModelForms&lt;/a&gt;). I use it to almost all my projects to
represent the data, along with &lt;a class="reference external" href="https://github.com/alex/django-filter"&gt;django-filter&lt;/a&gt; to create forms
to filter my model data. I&amp;#8217;ve written &lt;a class="reference external" href="http://stackoverflow.com/questions/13611741/django-tables-column-filtering/15129259#15129259"&gt;a nice &lt;span class="caps"&gt;SO&lt;/span&gt; answer&lt;/a&gt; with
instructions on how to use django-filter along with&amp;nbsp;django-tables2.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem-we-ll-solve"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;The problem we&amp;#8217;ll&amp;nbsp;solve&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The main tool django-tables2 offers is a template tag called &lt;tt class="docutils literal"&gt;render_table&lt;/tt&gt;
that get an instance of a subclass of &lt;tt class="docutils literal"&gt;django_tables2.Table&lt;/tt&gt;
which contains a description of the table (columns, style etc) along
with a queryset with the table&amp;#8217;s data and output it to the page. A nice
extra feature of render_table is that you could pass it just a simple
django queryset and it will output it without the need to create the
custom Table class. So you can do something like {% render_table User.objects.all() %}
and get a quick output of your Users&amp;nbsp;table.&lt;/p&gt;
&lt;p&gt;In one of my projects I had three models that
were used for keeping a different type of business log in the database (for auditing reasons)
and was using the above feature to display these logs to the administrators, just by
creating a very simple &lt;tt class="docutils literal"&gt;ListView&lt;/tt&gt; (a different one for each Log type) and using the
&lt;tt class="docutils literal"&gt;render_table&lt;/tt&gt; to display the data. So I&amp;#8217;d created three views like&amp;nbsp;this&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuditLogListView(ListView):
  model = AuditLog
  context_object_name = 'logs'
&lt;/pre&gt;
&lt;p&gt;which all used a single template that contained a line &lt;tt class="docutils literal"&gt;{% render_table logs %}&lt;/tt&gt; to display
the table (the &lt;tt class="docutils literal"&gt;logs&lt;/tt&gt; context variable contains the list of &lt;tt class="docutils literal"&gt;AuditLog&lt;/tt&gt; s).&lt;/p&gt;
&lt;p&gt;This was a nice &lt;span class="caps"&gt;DRY&lt;/span&gt; (but quick and dirty solution) that soon was not enough to fulfill the
needs of the administrators since they neeeded to have default sorting, filtering, hide
the primary key-id column etc. The obvious solution for that would be to just create three different
&lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; subclasses that
would more or less have the same options with only their &lt;tt class="docutils literal"&gt;model&lt;/tt&gt; attributte different. I didn&amp;#8217;t
like this solution that much since it seemed non-&lt;span class="caps"&gt;DRY&lt;/span&gt; to me and I would instead prefer to
create a generic &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; (that wouldn&amp;#8217;t have a &lt;tt class="docutils literal"&gt;model&lt;/tt&gt; attributte) and would just output
its data with the correct options &amp;#8212; so instead of three &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; classes I&amp;#8217;d like to create
just a single one with common options that would display its data (what &lt;tt class="docutils literal"&gt;render_table&lt;/tt&gt; does).&lt;/p&gt;
&lt;p&gt;Unfortunately, I couldn&amp;#8217;t find a solution to this, since when I ommited the &lt;tt class="docutils literal"&gt;model&lt;/tt&gt; attribute
from the &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; subclass nothing was outputed (there was no way to define fields to
display without also defining the model). An obvious (and &lt;span class="caps"&gt;DRY&lt;/span&gt;) resolution would be to create
a base &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; subclass that would define the needed options and create three subclasses
that would inherit from this class and override only the &lt;tt class="docutils literal"&gt;model&lt;/tt&gt; attribute. This unfortunately was not
possible becase &lt;a class="reference external" href="http://stackoverflow.com/questions/16696066/django-tables2-dynamically-adding-columns-to-table-not-adding-attrs-to-table/16741665#16741665"&gt;inheritance does not work well with django-tables2&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Furthermore, there&amp;#8217;s the extra hurdle of adding filtering to the above tables so that
the admin&amp;#8217;s would be able to quickly find a log message - if we wanted to use django-filter
we&amp;#8217;d need again to create three different subclasses (one for each log model type)
of &lt;tt class="docutils literal"&gt;django_filter.FilterSet&lt;/tt&gt; since
django-filter requires you to define the model for which the filter will be&amp;nbsp;created.&lt;/p&gt;
&lt;p&gt;The best way to resolve such problems is to create your classes dynamically when
you need &amp;#8216;em. I&amp;#8217;ve already described a way to &lt;a class="reference external" href="http://spapas.github.io/2013/12/24/django-dynamic-forms/"&gt;dynamically create forms in django
in a previous post&lt;/a&gt;. Below, I&amp;#8217;ll describe
a similar technique which can be used to create both dynamic tables and filters. Using
this methodology, you&amp;#8217;ll be able to add a new &lt;span class="caps"&gt;CBV&lt;/span&gt; that displays a table with
pagination, order and filtering for your model by just inheriting from a base&amp;nbsp;class!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-the-dynamic-table"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Adding the dynamic&amp;nbsp;table&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create the &lt;span class="caps"&gt;DRY&lt;/span&gt; &lt;span class="caps"&gt;CBV&lt;/span&gt; we&amp;#8217;ll use the &lt;a class="reference external" href="http://django-tables2.readthedocs.org/en/latest/pages/generic-mixins.html?highlight=singletableview"&gt;SingleTableView&lt;/a&gt; (&lt;tt class="docutils literal"&gt;django_tables2.SingleTableView&lt;/tt&gt;)
as a base and override its &lt;tt class="docutils literal"&gt;get_table_class&lt;/tt&gt; method to dynamically create our table class
using &lt;tt class="docutils literal"&gt;type&lt;/tt&gt;.
Here&amp;#8217;s how it could be done using a mixin (notice that this mixin should be used in a
&lt;tt class="docutils literal"&gt;SingleTableView&lt;/tt&gt; to override its &lt;tt class="docutils literal"&gt;get_table_class&lt;/tt&gt; method):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AddTableMixin(object, ):
  table_pagination = {&amp;quot;per_page&amp;quot;: 25}

  def get_table_class(self):
      def get_table_column(field):
          if isinstance(field, django.db.models.DateTimeField):
              return tables.DateColumn(&amp;quot;d/m/Y H:i&amp;quot;)
          else:
              return tables.Column()

      attrs = dict(
          (f.name, get_table_column(f)) for
          f in self.model._meta.fields if not f.name == 'id'
      )
      attrs['Meta'] = type('Meta', (), {'attrs':{&amp;quot;class&amp;quot;:&amp;quot;table&amp;quot;}, &amp;quot;order_by&amp;quot;: (&amp;quot;-created_on&amp;quot;, ) } )
      klass = type('DTable', (tables.Table, ), attrs)

      return klass
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s try to explain the &lt;tt class="docutils literal"&gt;get_table_class&lt;/tt&gt; method: First of all, we&amp;#8217;ve defined a local &lt;tt class="docutils literal"&gt;get_table_column&lt;/tt&gt;
function that will return a django-tables2 column depending on the field of the model. For example, in
our case we want to use a &lt;tt class="docutils literal"&gt;django_tables2.DateColumn&lt;/tt&gt; with a specific format when a &lt;tt class="docutils literal"&gt;DateTimeField&lt;/tt&gt; is
encountered and for all other model fields just use the stock &lt;tt class="docutils literal"&gt;Column&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;After that, we create a dictionary with all the attributes of the model. The &lt;tt class="docutils literal"&gt;self.model&lt;/tt&gt; field will contain
the model Class, so using its &lt;tt class="docutils literal"&gt;_meta.fields&lt;/tt&gt; will return the defined fields. As we can see, we just use
a generator expression to create a tuple with the name of the field and its type (using &lt;tt class="docutils literal"&gt;get_table_class&lt;/tt&gt;)
excluding the &amp;#8216;id&amp;#8217; column. So, attrs will be a dictionary of field names and&amp;nbsp;types.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;Meta&lt;/tt&gt; class of this table is crated using &lt;tt class="docutils literal"&gt;type&lt;/tt&gt; which creates a parentless class by defining all its attributes in a dictionary
and set it as the &lt;tt class="docutils literal"&gt;Meta&lt;/tt&gt; key in the previously defined &lt;tt class="docutils literal"&gt;attrs&lt;/tt&gt; dict. Finally, we create the actual &lt;tt class="docutils literal"&gt;django_tables2.Table&lt;/tt&gt; subclass by
inheriting from it and passing the &lt;tt class="docutils literal"&gt;attrs&lt;/tt&gt; dict. We&amp;#8217;ll see an example of what &lt;tt class="docutils literal"&gt;get_table_class&lt;/tt&gt; returns&amp;nbsp;later.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-a-dynamic-form-for-filtering"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Creating a dynamic form for&amp;nbsp;filtering&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s create another mixin that could be used to create a dynamic &lt;tt class="docutils literal"&gt;django.Form&lt;/tt&gt; subclass to the &lt;span class="caps"&gt;CBV&lt;/span&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AddFormMixin(object, ):
  def define_form(self):
      def get_form_field(f):
          return forms.CharField(required=False)

      attrs = dict(
          (f, get_form_field(f)) for
          f in self.get_form_fields() )

      klass = type('DForm', (forms.Form, ), attrs)

      return klass

  def get_queryset(self):
      form_class = self.define_form()
      if self.request.GET:
          self.form = form_class(self.request.GET)
      else:
          self.form = form_class()

      qs = super(AddFormMixin, self).get_queryset()

      if self.form.data and self.form.is_valid():
          q_objects = Q()
          for f in self.get_form_fields():
              q_objects &amp;amp;= Q(**{f+'__icontains':self.form.cleaned_data.get(f, '')})

          qs = qs.filter(q_objects)

      return qs

  def get_context_data(self, **kwargs):
      ctx = super(AddFormMixin, self).get_context_data(**kwargs)
      ctx['form'] = self.form
      return ctx
&lt;/pre&gt;
&lt;p&gt;The first method that will be called is the &lt;tt class="docutils literal"&gt;get_queryset&lt;/tt&gt; method that will generate the dynamic form
using &lt;tt class="docutils literal"&gt;define_form&lt;/tt&gt;. This method has a get_form_fields local function (similar to get_table_fields)
that can be used to override the types of the fields (or just fallback to a normal CharField) and
then create the &lt;tt class="docutils literal"&gt;attrs&lt;/tt&gt; dictionary and &lt;tt class="docutils literal"&gt;forms.Form&lt;/tt&gt; subclass in a similar way as the &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; subclass. Here,
we don&amp;#8217;t want to create a filter form from all fields of the model as we did on table, so instead
we&amp;#8217;ll use a &lt;tt class="docutils literal"&gt;get_form_fields&lt;/tt&gt; method that returns the name of the fields that we want to
use in the filtering form and needs to be defined in each &lt;span class="caps"&gt;CBV&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;get_queryset&lt;/tt&gt; method is more interesting: First of all, since we are just filtering the
queryset we&amp;#8217;d need to submit the form with a &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/tt&gt; (and not a &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/tt&gt;). We see that if we have
data to our &lt;tt class="docutils literal"&gt;request.&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/tt&gt; dictionary we&amp;#8217;ll instantiate the form using this data (or else we&amp;#8217;ll just
create an empty form). To do the actual filtering, we check if the form is valid and create a &lt;tt class="docutils literal"&gt;django.models.db.Q&lt;/tt&gt; object
that is used to combine (by &lt;span class="caps"&gt;AND&lt;/span&gt;) the conditions. Each of the individual Q objects that will be combined
to create the complete one will be created using the line &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Q(**{f+'__icontains':self.form.cleaned_data.get(f,&lt;/span&gt; &lt;span class="pre"&gt;'')})&lt;/span&gt;&lt;/tt&gt;
(where f will be the name of the field) which will create a dictionary of the form &lt;tt class="docutils literal"&gt;{'action__icontains': 'test text'}&lt;/tt&gt; and then pass this as a keyword
argument to the Q (using the &lt;tt class="docutils literal"&gt;**&lt;/tt&gt; mechanism) - this is the only way to pass dynamic kwargs to a&amp;nbsp;function!&lt;/p&gt;
&lt;p&gt;Finally, the queryset will be filtered using the combined &lt;tt class="docutils literal"&gt;Q&lt;/tt&gt; object we just&amp;nbsp;described.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-the-dynamic-cbv"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Creating the dynamic &lt;span class="caps"&gt;CBV&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the above mixins, we can easily create a dynamic &lt;span class="caps"&gt;CBV&lt;/span&gt; with a table and a filter form only by inheriting from the mixins
and &lt;tt class="docutils literal"&gt;SingleTableView&lt;/tt&gt; and defining the &lt;tt class="docutils literal"&gt;get_form_fields&lt;/tt&gt; method:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuditLogListView(AddTableMixin, AddFormMixin, SingleTableView):
  model = AuditLog
  context_object_name = 'logs'

  def get_form_fields(self):
      return ('action','user__username', )
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s suppose that the &lt;tt class="docutils literal"&gt;AuditLog&lt;/tt&gt; is defined as&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuditLog(models.Model):
  created_on = models.DateTimeField( auto_now_add=True, editable=False,)
  user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False,)
  action = models.CharField(max_length=256, editable=False,)
&lt;/pre&gt;
&lt;p&gt;Using the above &lt;tt class="docutils literal"&gt;AuditLogListView&lt;/tt&gt;, a dynamic table and a dynamic form will be automaticall created whenever the view is visited.
The &lt;tt class="docutils literal"&gt;Table&lt;/tt&gt; class will be like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class DTable(tables.Table):
  created_on = tables.DateColumn(&amp;quot;d/m/Y H:i&amp;quot;)
  user = tables.Column()
  action = tables.Column()

  class Meta:
      attrs = {&amp;quot;class&amp;quot;:&amp;quot;table&amp;quot;}
      order_by = (&amp;quot;-created_on&amp;quot;, )
&lt;/pre&gt;
&lt;p&gt;and the &lt;tt class="docutils literal"&gt;Form&lt;/tt&gt; class like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class DForm(forms.Form):
  user__username = forms.CharField()
  action = forms.CharField()
&lt;/pre&gt;
&lt;p&gt;An interesting thing to notice is that we can drill down to foreign keys (f.e. &lt;tt class="docutils literal"&gt;user__username&lt;/tt&gt;) to create more interesting filters. Also we could add some more
methods to be overriden by the implementing class beyond the &lt;tt class="docutils literal"&gt;get_form_fields&lt;/tt&gt;. For example, instead of using &lt;tt class="docutils literal"&gt;self.model._meta.fields&lt;/tt&gt;
to generate the fields of the table, we could instead use a &lt;tt class="docutils literal"&gt;get_table_fields&lt;/tt&gt; method that would be overriden in the implementing
classes (and even drill down on foreign keys to display more data on the table using &lt;a class="reference external" href="http://django-tables2.readthedocs.org/en/latest/pages/accessors.html"&gt;accessors&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Or, instead of just passing the the form field names we could also pass their type (instead of using &lt;tt class="docutils literal"&gt;get_form_fields&lt;/tt&gt;) and
their lookup method (instead of  &lt;tt class="docutils literal"&gt;icontains&lt;/tt&gt;) &amp;#8212; similar to&amp;nbsp;django-filter.&lt;/p&gt;
&lt;p&gt;Please notice that instead of creating a django form instance for filtering, we could instead create a django-filter instance with
a similar methodology. However, I preferred to just use a normal django form because it makes the whole process more clear and removes
a level of abstraction (we just create a &lt;tt class="docutils literal"&gt;django.Form&lt;/tt&gt; subclass while, if we used django-filter we&amp;#8217;d need to create a django-filter subclass
which would create a &lt;tt class="docutils literal"&gt;django.Form&lt;/tt&gt; subclass)!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the above technique we can quickly create a table and filter for a number of Models that all share
the same properties in the most &lt;span class="caps"&gt;DRY&lt;/span&gt;. This technique of course is useful only for quick CBVs that
are more or less the same and require little customization. Another interesting thing is that instead of
creating different &lt;tt class="docutils literal"&gt;SingleTableView&lt;/tt&gt; s we could instead create a single &lt;span class="caps"&gt;CBV&lt;/span&gt; that will get the content type
of the Model to be viewed as a parameter and retrieve the model (and queryset) from the content&amp;nbsp;type!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 05 Oct 2015 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-10-05:2015/10/05/django-dynamic-tables-similar-models/</guid><category>django</category><category>python</category><category>forms</category><category>tables</category></item><item><title>A (little more) complex react and flux example</title><link>http://spapas.github.io/2015/09/08/more-complex-react-flux-example/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id2"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#more-about-flux-components" id="id3"&gt;More about Flux&amp;nbsp;components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#explaining-the-application-components" id="id4"&gt;Explaining the application&amp;nbsp;components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#reusable-application-components" id="id5"&gt;Reusable application components&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#dropdown-react-js" id="id6"&gt;DropDown.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#datepicker-react-js" id="id7"&gt;DatePicker.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#pagingpanel-react-js" id="id8"&gt;PagingPanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#searchpanel-react-js" id="id9"&gt;SearchPanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#messagepanel" id="id10"&gt;MessagePanel&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#messagepanel-react-js" id="id11"&gt;MessagePanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#messagestore-js" id="id12"&gt;MessageStore.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#messageactions" id="id13"&gt;MessageActions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#non-reusable-application-components" id="id14"&gt;Non-reusable application components&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#booktable-react-js" id="id15"&gt;BookTable.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#authordialog-react-js" id="id16"&gt;AuthorDialog.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#authorpanel-react-js" id="id17"&gt;AuthorPanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#statpanel-react-js" id="id18"&gt;StatPanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#bookform-react-js" id="id19"&gt;BookForm.react.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#bookpanel-react-js" id="id20"&gt;BookPanel.react.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-actions" id="id21"&gt;The&amp;nbsp;Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-stores" id="id22"&gt;The Stores&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#id1" id="id23"&gt;MessageStore.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#authorstore-js" id="id24"&gt;AuthorStore.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#categorystore-js" id="id25"&gt;CategoryStore.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#bookstore-js" id="id26"&gt;BookStore.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id27"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a class="reference external" href="http://spapas.github.io/2015/06/05/comprehensive-react-flux-tutorial/"&gt;previous&lt;/a&gt;
&lt;a class="reference external" href="http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/"&gt;two&lt;/a&gt; parts of this series, we have seen
how we could implement a
not-so-simple single page application with full &lt;span class="caps"&gt;CRUD&lt;/span&gt; capabilities
using react only (in the &lt;a class="reference external" href="http://spapas.github.io/2015/06/05/comprehensive-react-flux-tutorial/"&gt;first part&lt;/a&gt; ) and then how to
change it to use the flux architecture (in the &lt;a class="reference external" href="http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/"&gt;second part&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;In this, third, part, we will
add some more capabilities to the previous app
to prove how easy it is to create complex apps
and continue the discussion on
the Flux architecture. The source code of this project
can
be found at &lt;a class="reference external" href="https://github.com/spapas/react-tutorial"&gt;https://github.com/spapas/react-tutorial&lt;/a&gt; (tag name&amp;nbsp;react-flux-complex).&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a demo of the final&amp;nbsp;application:&lt;/p&gt;
&lt;img alt="Our project" src="/images/demo2.gif" style="width: 780px;" /&gt;
&lt;p&gt;We can see that, when compared to the previous version this one&amp;nbsp;has:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Sorting by table&amp;nbsp;columns&lt;/li&gt;
&lt;li&gt;Pagination&lt;/li&gt;
&lt;li&gt;Message for&amp;nbsp;loading&lt;/li&gt;
&lt;li&gt;Client side url updating (with&amp;nbsp;hashes)&lt;/li&gt;
&lt;li&gt;Cascading drop downs (selecting category will filter out&amp;nbsp;subcategories)&lt;/li&gt;
&lt;li&gt;Integration with jquery-ui&amp;nbsp;datepicker&lt;/li&gt;
&lt;li&gt;Add a child object&amp;nbsp;(author)&lt;/li&gt;
&lt;li&gt;Add authors with a modal dialog&amp;nbsp;(popup)&lt;/li&gt;
&lt;li&gt;Delete authors (using the &amp;quot;-&amp;quot;&amp;nbsp;button)&lt;/li&gt;
&lt;li&gt;Colored ajax result messages (green when all is ok, red with&amp;nbsp;error)&lt;/li&gt;
&lt;li&gt;A statistics panel (number of books /&amp;nbsp;authors)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the paragraphs below, beyond the whole architecture, we&amp;#8217;ll see
a bunch of techniques such&amp;nbsp;as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Creating reusable flux&amp;nbsp;components&lt;/li&gt;
&lt;li&gt;Integrating react with&amp;nbsp;jquery&lt;/li&gt;
&lt;li&gt;Creating cascading&amp;nbsp;dropdowns&lt;/li&gt;
&lt;li&gt;Updating URLs with&amp;nbsp;hashes&lt;/li&gt;
&lt;li&gt;Adding pagination/sorting/querying to a table of&amp;nbsp;results&lt;/li&gt;
&lt;li&gt;Displaying pop&amp;nbsp;ups&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="more-about-flux-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;More about Flux&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before delving into the source code of the above application, I&amp;#8217;d like to
make crystal what is the proposed way to call methods in the flux chain
and which types of components can include other types of components. Let&amp;#8217;s
take a look at the following&amp;nbsp;diagram:&lt;/p&gt;
&lt;img alt="flux dependencies" src="/images/react_flux_deps1.png" style="width: 480px;" /&gt;
&lt;p&gt;The arrows display the dependencies of the Flux architecture - an arrow
from X to Y means that a component of type Y could depend on an Component
of type X (of example, a store could depend on an action or another store
but not on a&amp;nbsp;panel).&lt;/p&gt;
&lt;p&gt;In more detail, we can see that in the top of the hierarchy,
having no dependencies are the
Dispatcher and the Constants. The Dispatcher is just a single component
(which actually is a singleton - only one dispatcher exists in each
single page react-flux application)
that inherits from the Facebook&amp;#8217;s dispatcher and is imported by the
action components (since action methods defined in action components
call the &lt;tt class="docutils literal"&gt;dispatch&lt;/tt&gt; method of the dispatcher passing the correct
parameters) and the stores which do the real actions when an action
is dispatched, depending on the action type. The Constant components
define constant values for the action types and are used by both
the actions (to set the action types to the dispatch calls) and by
the stores to be used on the switch statement when an action is
dispatched. As an example, for BookActions we have the&amp;nbsp;following&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookConstants = require('../constants/BookConstants')
var AppDispatcher = require('../dispatcher/AppDispatcher').AppDispatcher;

var BookActions = {
    change_book: function(book) {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_CHANGE,
            book: book
        });
    },
// Other book actions [...]
&lt;/pre&gt;
&lt;p&gt;and for&amp;nbsp;BookStore&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var $ = require('jquery');
var AppDispatcher = require('../dispatcher/AppDispatcher').AppDispatcher;
var BookConstants = require('../constants/BookConstants')

// [...]

BookStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.BOOK_EDIT:
            _editBook(action.book);
        break;
// [...] other switch branches
&lt;/pre&gt;
&lt;p&gt;An interesting thing to see is that the actions depend only on the Dispatcher
and on the Constants, while the stores also depend on actions (not only
from the same action types as the store type, for example AuthorStore depends
on both AuthorActions and MessageActions) and on &lt;em&gt;other&lt;/em&gt; stores. This means
that the actions should be a &amp;quot;clean&amp;quot; component: Just declare your action methods
whose only purpose is to pass the action type along with the required parameters
to the&amp;nbsp;dispatcher.&lt;/p&gt;
&lt;p&gt;On the other hand, the stores are depending on both actions and other stores.
The action dependency is because sometimes when something is done in a store
we need to notify another store to do something as a response to that. For
example, in our case, when a book is updated we need to notify the message
store to show the &amp;quot;Book updated ok&amp;quot; message. This preferrably should not be done by
directly calling the corresponding method on the message store but instead
by calling the corresponding action of MessageAction and passing the correct
parameters (actually, the method that updates the message in MessageStore
should be a private method that is called &lt;em&gt;only&lt;/em&gt; through the&amp;nbsp;action).&lt;/p&gt;
&lt;p&gt;One thing to notice here is that you &lt;em&gt;cannot&lt;/em&gt; call (and dispatch) an action in the
same call stack (meaning it is directly called) as of another dispatch or you&amp;#8217;ll get a
&lt;tt class="docutils literal"&gt;Invariant Violation: &lt;span class="pre"&gt;Dispatch.dispatch(...):&lt;/span&gt; Cannot dispatch in the middle of a dispatch.&lt;/tt&gt;
error in your javascript console. Let&amp;#8217;s see an example of what this means and how
to avoid it because its a common error. Let&amp;#8217;s say that we have the following
code to a&amp;nbsp;store:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case Constants.TEST_ERR:
            TestActions.action1();
        break;
        case Constants.TEST_OK1:
            setTimeout(function() {
                TestActions.action1();
            }, 0);

        break;
        case Constants.TEST_OK2:
            $.get('/get/', function() {
                TestActions.action1();
            });

        break;
    }
    return true;
});
&lt;/pre&gt;
&lt;p&gt;Here, the &lt;tt class="docutils literal"&gt;TEST_ERR&lt;/tt&gt; branch will throw an error because the &lt;tt class="docutils literal"&gt;TestAction.action1&lt;/tt&gt; is &lt;em&gt;in the same call stack&lt;/em&gt;
as this dispatch! On the other hand, both &lt;tt class="docutils literal"&gt;TEST_OK1&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;TEST_OK2&lt;/tt&gt; will work: &lt;tt class="docutils literal"&gt;TEST_OK2&lt;/tt&gt; is the most
usual, since most of the times we want to call an action as a result of an ajax call - however, sometimes we
want to call an action without any ajax &amp;#8212; in this case we use the setTimeout (with a timeout of 0 ms) in
order to move the call to &lt;tt class="docutils literal"&gt;TestActions.action1()&lt;/tt&gt; to a different call&amp;nbsp;stack.&lt;/p&gt;
&lt;p&gt;Now, as I mentioned before, there&amp;#8217;s also a &lt;em&gt;different-store&lt;/em&gt; dependency on stores.
This dependency is needed because some stores may offer public methods for other stores to use
(methods that don&amp;#8217;t actually need to be dispatched through the dispatcher) and
for the &lt;tt class="docutils literal"&gt;waitFor&lt;/tt&gt; method , in case there are two different
stores that respond to a single action and want to have one store executing
its dispatch method before the other.
(the waitFor method takes the dispatchToken, which is the result of &lt;tt class="docutils literal"&gt;Dispatcher.register&lt;/tt&gt; of
a different store as a parameter in order to wait for that action to&amp;nbsp;finish).&lt;/p&gt;
&lt;p&gt;Finally, the Panels depend on both actions (to initiate an action as a response
to user input) and stores (to read the state of the each required store when it
is changed). Of course, not all panels actually depend on stores, since as we
already know the state of a React app should be kept as high in the hierarchy
as possible, so a central component will get the state of a store and pass the
required state attributes to its children through parameters. On the other
hand, every component that responds to user input will have to import
am action object and call the corresponding method &amp;#8212; we should never pass
callbacks from a parent to a child component as a parameter anymore &lt;em&gt;unless&lt;/em&gt;
we want to make the component reusable (more on this&amp;nbsp;later).&lt;/p&gt;
&lt;p&gt;Finally, as expected, because of their hierarchy the compoents depend on their
child components (a BookTable depends on a BookTableRow&amp;nbsp;etc).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="explaining-the-application-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Explaining the application&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a lot of components that are needed for
the above application. A bird&amp;#8217;s eye view of the components
and their hierarchies can be seen on the following&amp;nbsp;figure:&lt;/p&gt;
&lt;img alt="Our components" src="/images/complex_react_components.png" style="width: 780px;" /&gt;
&lt;p&gt;We will first explain a bit the components that could be easily reused
by other applications and after that the components that are specifically
implemented for our book/author single page&amp;nbsp;application.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="reusable-application-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Reusable application&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can see that beyond the specific components (&lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt; etc)
there&amp;#8217;s a bunch of more general components (&lt;tt class="docutils literal"&gt;DropDown&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;DatePicker&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;PagingPanel&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;MessagePanel&lt;/tt&gt;) that have names like they could be used by other applications (for example every application
that wants to implement a DropDown could use our component) and not only by the
Book-Author application. Let&amp;#8217;s take a quick look at these components and if they
are actually&amp;nbsp;reusable:&lt;/p&gt;
&lt;div class="section" id="dropdown-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;DropDown.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');

var DropDown = React.createClass({
    render: function() {
        var options = [];
        options.push(&amp;lt;option key='-1' value='' &amp;gt;---&amp;lt;/option&amp;gt;);
        if(this.props.options) {
            this.props.options.forEach(function(option) {
                options.push(&amp;lt;option key={option.id} value={option.id}&amp;gt;{option.name}&amp;lt;/option&amp;gt;);
            });
        }

        return(
            &amp;lt;select ref='dropdown' value={this.props.value?this.props.value:''} onChange={this.onFormChange} &amp;gt;
                {options}
            &amp;lt;/select&amp;gt;
        );
    },
    onFormChange: function() {
        var val = React.findDOMNode(this.refs.dropdown).value
        this.props.dropDownValueChanged(val);
    }
});

module.exports.DropDown = DropDown;
&lt;/pre&gt;
&lt;p&gt;What we see here is that this component does not actually have a local state and will need three&amp;nbsp;parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the list of options (&lt;tt class="docutils literal"&gt;props.options&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;the curently selected option (&lt;tt class="docutils literal"&gt;props.value&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;a callback to be called when the dropdown is changed (&lt;tt class="docutils literal"&gt;props.dropDownValueChanged&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By passing the above three parameters this dropdown component can be reused whenever a dropdown is needed!
As we can see here we need to pass a callback function to this dropdown and call the corresponding action
directly. This is important to have a reusable component: The component that includes each dropdown decides
which should be the action on the dropdown value change. Another option if we wanted to avoid callbacks
would be to pass an identifier as a property for each dropdown and the dropdown would call a generic
dropdown action and passing this identifier &amp;#8212; however I think that actually passing the callback is
easier and makes the code much more&amp;nbsp;readable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="datepicker-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;DatePicker.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The datepicker component has more or less the same structure as with the dropdown: It needs one parameter
for its current value (&lt;tt class="docutils literal"&gt;props.value&lt;/tt&gt;) and another as the callback to the function when the date is
changed (once again this is required to have a reusable&amp;nbsp;component):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');

var DatePicker = React.createClass({
    render: function() {
        return(
            &amp;lt;input type='text' ref='date' value={this.props.value} onChange={this.handleChange} /&amp;gt;
        );
    },
    componentDidMount: function() {
        $(React.findDOMNode(this)).datepicker({ dateFormat: 'yy-mm-dd' });
        $(React.findDOMNode(this)).on('change', this.handleChange);
    },
    componentWillUnmount: function() {

    },
    handleChange: function() {
        var date = React.findDOMNode(this.refs.date).value
        this.props.onChange(date);
    }
});

module.exports.DatePicker = DatePicker ;
&lt;/pre&gt;
&lt;p&gt;Another thing we can see here is how can integrate jquery components with react: When
the component is mounted, we get its &lt;span class="caps"&gt;DOM&lt;/span&gt; component using &lt;tt class="docutils literal"&gt;React.findDomNode(this)&lt;/tt&gt; and
convert it to a datepicker. We also set its change function to be the passed&amp;nbsp;callback.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pagingpanel-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;PagingPanel.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The paging panel is not actually a reusable component because it requires BookActions
(to handle next and previous page clicks) - so
it can&amp;#8217;t be used by Authors (if authors was a table that is). However, we can easily
change it to be reusable if we passed callbacks for next and previous page so that
the component including PagingPanel would call the correct action on each click. Having
a reusable PagingPangel is not needed for our application since only books have a&amp;nbsp;table.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookActions = require('../actions/BookActions').BookActions;

var PagingPanel = React.createClass({
    render: function() {
        return(
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                {this.props.page==1?'':&amp;lt;button onClick={this.onPreviousPageClick}&amp;gt;&amp;amp;lt;&amp;lt;/button&amp;gt;}
                &amp;amp;nbsp; Page {this.props.page} of {this.getTotalPages()} &amp;amp;nbsp;
                {this.props.page==this.getTotalPages()?'':&amp;lt;button onClick={this.onNextPageClick} &amp;gt;&amp;amp;gt;&amp;lt;/button&amp;gt;}
            &amp;lt;/div&amp;gt;
        );
    },
    onNextPageClick: function(e) {
        e.preventDefault();
        BookActions.change_page(this.props.page+1)
    },
    onPreviousPageClick: function(e) {
        e.preventDefault();
        BookActions.change_page(this.props.page-1)
    },
    getTotalPages: function() {
        return Math.ceil(this.props.total / this.props.page_size);
    }
})

module.exports.PagingPanel = PagingPanel;
&lt;/pre&gt;
&lt;p&gt;The component is very simple, it needs three&amp;nbsp;parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the current page (&lt;tt class="docutils literal"&gt;props.page&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;the page size (&lt;tt class="docutils literal"&gt;props.page_size&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;the total pages number (&lt;tt class="docutils literal"&gt;props.total&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and just displayd the current page along with buttons to go to the next or previous page (if these buttons should be visible of&amp;nbsp;course).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="searchpanel-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9"&gt;SearchPanel.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The SearchPanel is another panel that could be reusable if we&amp;#8217;d passed a callbeck instead of calling the &lt;tt class="docutils literal"&gt;BookActions.search&lt;/tt&gt;
action directly. The promise behavior has been explained in the previous posts and is needed to buffer the queries to the
server when a user types his search&amp;nbsp;query.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookActions = require('../actions/BookActions').BookActions;

var SearchPanel = React.createClass({
    getInitialState: function() {
        return {
            search: this.props.query,
        }
    },
    componentWillReceiveProps: function(nextProps) {
      this.setState({
            search: nextProps.query
      });
    },
    render: function() {
        return (
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                &amp;lt;div className=&amp;quot;one-fourth column&amp;quot;&amp;gt;
                    Filter: &amp;amp;nbsp;
                    &amp;lt;input ref='search' name='search' type='text' value={this.state.search} onChange={this.onSearchChange} /&amp;gt;
                    {this.state.search?&amp;lt;button onClick={this.onClearSearch} &amp;gt;x&amp;lt;/button&amp;gt;:''}
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    },
    onSearchChange: function() {
        var query = React.findDOMNode(this.refs.search).value;
        if (this.promise) {
            clearInterval(this.promise)
        }
        this.setState({
            search: query
        });
        this.promise = setTimeout(function () {
            BookActions.search(query);
        }.bind(this), 400);
    },
    onClearSearch: function() {
        this.setState({
            search: ''
        });
        BookActions.search('');
    }
});

module.exports.SearchPanel = SearchPanel;
&lt;/pre&gt;
&lt;p&gt;As we can see, this panel is a little different than the previous ones because it actually handles its
own local state: When the component should get properties from its parent compoent, its state will
be updated to the &lt;tt class="docutils literal"&gt;query&lt;/tt&gt; attribute - so the current value of the search query gets updated through
properties. However, when the value of the search input is changed, we see that the local state is
changed immediately but the &lt;tt class="docutils literal"&gt;BookActions.search&lt;/tt&gt; (or the corresponding callback) gets called &lt;em&gt;only&lt;/em&gt;
when the timeout has&amp;nbsp;passed!&lt;/p&gt;
&lt;p&gt;The above means that we can type whatever we want on the search input, but it at first it will be used
only locally to immediately update the value of the input and, only after the timeout has fired the
search action will be called. If we hadn&amp;#8217;t used the local state it would be much more difficult to have
this consistent behavior (we&amp;#8217;d need to add two actions, one to handle the search query value change
and another to handle the timeout firing &amp;#8212; making everythimg much more&amp;nbsp;complicated).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="messagepanel"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10"&gt;MessagePanel&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The MessagePanel is really interesting because it is a reusable component that actually has its own action and store module! This
component can be reused in &lt;em&gt;different&lt;/em&gt; applications that need to display message but &lt;em&gt;not&lt;/em&gt; on the same application (because a single state
is kept for all messages). If we wanted to use a different MessagePanel for Books or Authors then we&amp;#8217;d need to keep both in the
state &lt;em&gt;and&lt;/em&gt; also it to the action to differentiate between messages for author and for book. Instead, by keeping a single Messages
state for both Books and Authors we have a much more simple&amp;nbsp;version.&lt;/p&gt;
&lt;div class="section" id="messagepanel-react-js"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id11"&gt;MessagePanel.react.js&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The MessagePanel component has a local state which responds to changes on MessageStore. When the
state of MessageStore is changed the MessagePanel will be re-rendered with the new&amp;nbsp;message.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var MessageStore = require('../stores/MessageStore').MessageStore;

var MessagePanel = React.createClass({
    getInitialState: function() {
        return {

        };
    },
    render: function() {
        return(
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                {this.state.message?&amp;lt;div className={this.state.message.color}&amp;gt;{this.state.message.text}&amp;lt;/div&amp;gt;:&amp;quot;&amp;quot;}
            &amp;lt;/div&amp;gt;
        );
    },
    _onChange: function() {
        this.setState(MessageStore.getState());
    },
    componentWillUnmount: function() {
        MessageStore.removeChangeListener(this._onChange);
    },
    componentDidMount: function() {
        MessageStore.addChangeListener(this._onChange);
    }
})

module.exports.MessagePanel = MessagePanel;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="messagestore-js"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id12"&gt;MessageStore.js&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The MessageStore has a (private) state containing a &lt;tt class="docutils literal"&gt;message&lt;/tt&gt; that gets updated
only when the ccorresponding action is dispached. The store has a single state
for all messages - it doesn&amp;#8217;t care if the messages are for books or&amp;nbsp;authors.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var $ = require('jquery');
var EventEmitter = require('events').EventEmitter;
var AppDispatcher = require('../dispatcher/AppDispatcher').AppDispatcher;
var BookConstants = require('../constants/BookConstants')

var _state = {
    message: {}
};

var MessageStore = $.extend({}, EventEmitter.prototype, {
    getState: function() {
        return _state;
    },
    emitChange: function() {
        this.emit('change');
    },
    addChangeListener: function(callback) {
        this.on('change', callback);
    },
    removeChangeListener: function(callback) {
        this.removeListener('change', callback);
    }
});

MessageStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.MESSAGE_ADD:
            _state.message = action.message;
            MessageStore.emitChange();
        break;
    }
    return true;
});

module.exports.MessageStore = MessageStore;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="messageactions"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id13"&gt;MessageActions&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Finally, there are two actions that are defined for the MessageStore: One for adding
an ok message and one for adding an error message - both of which have the same
message type (but pass a different color&amp;nbsp;parameter).&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var AppDispatcher = require('../dispatcher/AppDispatcher').AppDispatcher;
var BookConstants = require('../constants/BookConstants')

var MessageActions = {
    add_message_ok: function(msg) {
        AppDispatcher.dispatch({
            actionType: BookConstants.MESSAGE_ADD,
            message: {
                color: 'green',
                text: msg
            }
        });
    },
    add_message_error: function(msg) {
        AppDispatcher.dispatch({
            actionType: BookConstants.MESSAGE_ADD,
            message: {
                color: 'green',
                text: msg
            }
        });
    }
};

module.exports.MessageActions = MessageActions;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="non-reusable-application-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id14"&gt;Non-reusable application&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I don&amp;#8217;t want to discuss the source code for all the non-reusable components since some of them
are more or less the same with the previous version and are easy to understand just by
checking the source code (BookTableRow and ButtonPanel). However, I&amp;#8217;ll
discuss the other, more complex components starting from the inside of the&amp;nbsp;react-onion:&lt;/p&gt;
&lt;div class="section" id="booktable-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15"&gt;BookTable.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I want to display this component to discuss how sorting is implemented: Each column has a key which,
when passed to django-rest-framework will sort the results based on that key (the &lt;tt class="docutils literal"&gt;__&lt;/tt&gt; does a
join so by &lt;tt class="docutils literal"&gt;author__last_name&lt;/tt&gt; we mean that we want to sort by the last_name field of the author
of each book. Also, you can pass the key as it is to sort ascending or with a minus (-) in front
(for example &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-author__last_name&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookTableRow = require('./BookTableRow.react').BookTableRow;
var BookActions = require('../actions/BookActions').BookActions;

var BookTable = React.createClass({
    render: function() {
        var rows = [];
        this.props.books.forEach(function(book) {
            rows.push(&amp;lt;BookTableRow key={book.id} book={book} /&amp;gt;);
        });
        return (
            &amp;lt;table&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'id')}&amp;gt;{this.showOrdering('id')} Id&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'title')}&amp;gt;{this.showOrdering('title')} Title&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'subcategory__name')}&amp;gt;{this.showOrdering('subcategory__name')} Category&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'publish_date')}&amp;gt;{this.showOrdering('publish_date')} Publish date&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'author__last_name')}&amp;gt;{this.showOrdering('author__last_name')} Author&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Edit&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                &amp;lt;tbody&amp;gt;{rows}&amp;lt;/tbody&amp;gt;
            &amp;lt;/table&amp;gt;
        );
    },
    onClick: function(v, e) {
        e.preventDefault();
        BookActions.sort_books(v);
    },
    showOrdering: function(v) {
        if (v==this.props.ordering) {
            return '+'
        } else if ('-'+v==this.props.ordering) {
            return '-'
        }
    }
});

module.exports.BookTable = BookTable ;
&lt;/pre&gt;
&lt;p&gt;The only thing that needs explaining in this module is the line of the&amp;nbsp;form&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;th&amp;gt;&amp;lt;a href='#' onClick={this.onClick.bind(this, 'id')}&amp;gt;{this.showOrdering('id')} Id&amp;lt;/a&amp;gt;&amp;lt;/th&amp;gt;
&lt;/pre&gt;
&lt;p&gt;that creates the title of each column and triggers ascending or descending sorting on this column by
clicking on it. So, we can see that we&amp;#8217;ve create an onClick function that actually expects a value - the key
to that column. To allow passing that value, we use the bind method of the function object which will
create new a function that has this key as its first parameter. If we didn&amp;#8217;t want to use bind, we&amp;#8217;d need to
creatre 5 different function (onIdClick, onTitleClick etc)! The most common usage of &lt;tt class="docutils literal"&gt;bind&lt;/tt&gt; is to actually &lt;em&gt;bind&lt;/em&gt;
a function to an object (that&amp;#8217;s what the first parameter to this function does)
so that calling this inside that function will refer to that object - here we leave the binding
of the function to the same object and only do the parameter&amp;nbsp;passing.&lt;/p&gt;
&lt;p&gt;Also, the showOrdering checks if the current ordering is the same as that column&amp;#8217;s key and displays
either a + (for ascending) or - (for descending) in front of the column&amp;nbsp;title.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="authordialog-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16"&gt;AuthorDialog.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is a handmade pop-up dialog that gets displayed when a new author is added (the + button is clicked)
using only css to center it on the screen when it is displayed.
We can see that it is either visible on invisible based on the &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt; input property which actually
is the only input this component requires. When it is visible and the ok or cancel button are pressed
the corresponding action will be dispatched (which will actually close this popup by setting the &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt;
to&amp;nbsp;false):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var AuthorActions = require('../actions/AuthorActions').AuthorActions;

var AuthorDialog = React.createClass({

    render: function() {
        if (!this.props.showDialog) {
            return (
                &amp;lt;div /&amp;gt;
            )
        } else {
            return(
                &amp;lt;div className='modal-dialog' id=&amp;quot;dialog-form&amp;quot;  &amp;gt;
                    &amp;lt;label htmlFor=&amp;quot;first_name&amp;quot;&amp;gt;First name:&amp;lt;/label&amp;gt; &amp;lt;input type='text' ref='first_name' name='first_name' /&amp;gt; &amp;lt;br /&amp;gt;
                    &amp;lt;label htmlFor=&amp;quot;last_name&amp;quot;&amp;gt;Last name:&amp;lt;/label&amp;gt; &amp;lt;input type='text' ref='last_name' name='last_name' /&amp;gt; &amp;lt;br /&amp;gt;
                    &amp;lt;button onClick={this.onOk}&amp;gt;Ok&amp;lt;/button&amp;gt;
                    &amp;lt;button onClick={this.onCancel} &amp;gt;Cancel&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;

            );
        }
    },
    onCancel: function(e) {
        e.preventDefault();
        AuthorActions.hide_add_author();
    },
    onOk: function(e) {
        e.preventDefault();
        first_name = React.findDOMNode(this.refs.first_name).value;
        last_name = React.findDOMNode(this.refs.last_name).value;
        AuthorActions.add_author_ok({
            first_name: first_name,
            last_name: last_name
        });
    }
});

module.exports.AuthorDialog = AuthorDialog ;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="authorpanel-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id17"&gt;AuthorPanel.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The AuthorPanel displays the author select DropDown along with the + (add author) and
- (delete author) buttons. It also contains the AuthorDialog which will be displayed
or not depending on the value of the &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt; property.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var DropDown = require('./DropDown.react').DropDown;
var AuthorDialog = require('./AuthorDialog.react').AuthorDialog;
var AuthorActions = require('../actions/AuthorActions').AuthorActions;

var AuthorPanel = React.createClass({
    getInitialState: function() {
        return {};
    },
    render: function() {
        var authorExists = false ;
        if(this.props.authors) {
            var ids = this.props.authors.map(function(x) {
                return x.id*1;
            });

            if(ids.indexOf(1*this.props.author)&amp;gt;=0 ) {
                authorExists = true;
            }
        }

        return(
            &amp;lt;div className='one-half column'&amp;gt;
                &amp;lt;AuthorDialog showDialog={this.props.showDialog} /&amp;gt;
                &amp;lt;label forHtml='date'&amp;gt;Author&amp;lt;/label&amp;gt;
                &amp;lt;DropDown options={this.props.authors} dropDownValueChanged={this.props.onAuthorChanged} value={authorExists?this.props.author:''} /&amp;gt;
                &amp;lt;button onClick={this.addAuthor} &amp;gt;+&amp;lt;/button&amp;gt;
                {authorExists?&amp;lt;button onClick={this.deleteAuthor}&amp;gt;-&amp;lt;/button&amp;gt;:&amp;quot;&amp;quot;}
            &amp;lt;/div&amp;gt;
        );
    },
    addAuthor: function(e) {
        e.preventDefault();
        console.log(&amp;quot;ADD AUTHOR&amp;quot;);
        AuthorActions.show_add_author();
    },
    deleteAuthor: function(e) {
        e.preventDefault();
        AuthorActions.delete_author(this.props.author);
        console.log(&amp;quot;DELETE AUTHOR&amp;quot;);
        console.log(this.props.author);
    },
});

module.exports.AuthorPanel = AuthorPanel;
&lt;/pre&gt;
&lt;p&gt;As we can see, there are three properties that are passed to this&amp;nbsp;component:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;props.author&lt;/tt&gt;: The currently selected&amp;nbsp;author&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;props.authors&lt;/tt&gt;: The list of all&amp;nbsp;authors&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;props.onAuthorChanged&lt;/tt&gt;: A callback that is called when the author is changed. Here, we could have used an action (just like for add/delete author) instead of a callback, however its not actually required. When the author is changed, it means that the currently edited book&amp;#8217;s author is changed. So we could propagate the change to the parent (form) component that handles the book change along with the other changes (i.e title, publish date&amp;nbsp;etc).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="statpanel-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18"&gt;StatPanel.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The StatPanel is an interesting, read-only component that displays the number of
authors and books. This component requests updates from both the &lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;AuthorStore&lt;/tt&gt; - when their state is updated the component will be re-rendered
with the number of books and&amp;nbsp;authors:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookStore = require('../stores/BookStore').BookStore;
var AuthorStore = require('../stores/AuthorStore').AuthorStore;

var StatPanel = React.createClass({
    getInitialState: function() {
        return {};
    },
    render: function() {
        var book_len = '-';
        var author_len = '-';
        if(this.state.books) {
            book_len = this.state.books.length
        }
        if(this.state.authors) {
            author_len = this.state.authors.length
        }
        return(
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    Books number: {book_len}
                &amp;lt;/div&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    Authors number: {author_len}
                &amp;lt;/div&amp;gt;
                &amp;lt;br /&amp;gt;
            &amp;lt;/div&amp;gt;
        );
    },
    _onBookChange: function() {
        this.setState({
            books:BookStore.getState().books
        });
    },
    _onAuthorChange: function() {
        this.setState({
            authors: AuthorStore.getState().authors
        });
    },
    componentWillUnmount: function() {
        AuthorStore.removeChangeListener(this._onAuthorChange);
        BookStore.removeChangeListener(this._onBookChange);
    },
    componentDidMount: function() {
        AuthorStore.addChangeListener(this._onAuthorChange);
        BookStore.addChangeListener(this._onBookChange);
    }
});

module.exports.StatPanel = StatPanel ;
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ve added different change listeners in case we wanted to do
some more computations for book or author change (instead of just
getting their books / authors property). Of course the same behavior
could be achieved with just a single change listener that would
get both the books and&amp;nbsp;authors.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bookform-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id19"&gt;BookForm.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The BookForm is one of the most complex panels of this application (along with BookPanel) because
it actually contains a bunch of other panels and has some callbacks for them to&amp;nbsp;use.&lt;/p&gt;
&lt;p&gt;We can see that, as explained before, when the current book form values are changed (through callbacks) the change_book action will be&amp;nbsp;called.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookActions = require('../actions/BookActions').BookActions;
var DropDown = require('./DropDown.react.js').DropDown;
var StatPanel = require('./StatPanel.react.js').StatPanel;
var MessagePanel = require('./MessagePanel.react.js').MessagePanel;
var DatePicker = require('./DatePicker.react.js').DatePicker;
var ButtonPanel = require('./ButtonPanel.react.js').ButtonPanel;
var AuthorPanel = require('./AuthorPanel.react.js').AuthorPanel;
var CategoryStore = require('../stores/CategoryStore').CategoryStore;
var AuthorStore = require('../stores/AuthorStore').AuthorStore;
var loadCategories = require('../stores/CategoryStore').loadCategories;
var loadAuthors = require('../stores/AuthorStore').loadAuthors;

var BookForm = React.createClass({
    getInitialState: function() {
        return {};
    },
    render: function() {
        return(
            &amp;lt;form onSubmit={this.onSubmit}&amp;gt;
                &amp;lt;div className='row'&amp;gt;
                    &amp;lt;div className='one-half column'&amp;gt;
                        &amp;lt;label forHtml='title'&amp;gt;Title&amp;lt;/label&amp;gt;
                        &amp;lt;input ref='title' name='title' type='text' value={this.props.book.title} onChange={this.onTitleChange} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div className='one-half column'&amp;gt;
                        &amp;lt;label forHtml='date'&amp;gt;Publish date&amp;lt;/label&amp;gt;
                        &amp;lt;DatePicker ref='date' onChange={this.onDateChange} value={this.props.book.publish_date} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className='row'&amp;gt;
                    &amp;lt;div className='one-half column'&amp;gt;
                        &amp;lt;label forHtml='category'&amp;gt;Category&amp;lt;/label&amp;gt;
                        &amp;lt;DropDown options={this.state.categories} dropDownValueChanged={this.onCategoryChanged} value={this.props.book.category} /&amp;gt;
                        &amp;lt;DropDown options={this.state.subcategories} dropDownValueChanged={this.onSubCategoryChanged} value={this.props.book.subcategory} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;AuthorPanel authors={this.state.authors} author={this.props.book.author} onAuthorChanged={this.onAuthorChanged} showDialog={this.state.showDialog} /&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;ButtonPanel book={this.props.book}  /&amp;gt;
                &amp;lt;MessagePanel /&amp;gt;
                &amp;lt;StatPanel  /&amp;gt;
            &amp;lt;/form&amp;gt;
        );
    },
    onSubmit: function(e) {
        e.preventDefault();
        BookActions.save(this.props.book)
    },
    onTitleChange: function() {
        this.props.book.title = React.findDOMNode(this.refs.title).value;
        BookActions.change_book(this.props.book);
    },
    onDateChange: function(date) {
        this.props.book.publish_date = date;
        BookActions.change_book(this.props.book);
    },
    onCategoryChanged: function(cat) {
        this.props.book.category = cat;
        this.props.book.subcategory = '';
        BookActions.change_book(this.props.book);
    },
    onSubCategoryChanged: function(cat) {
        this.props.book.subcategory = cat;
        BookActions.change_book(this.props.book);
    },
    onAuthorChanged: function(author) {
        this.props.book.author = author;
        BookActions.change_book(this.props.book);
    },
    _onChangeCategories: function() {
        this.setState(CategoryStore.getState());
    },
    _onChangeAuthors: function() {
        this.setState(AuthorStore.getState());
    },
    componentWillUnmount: function() {
        CategoryStore.removeChangeListener(this._onChangeCategories);
        AuthorStore.removeChangeListener(this._onChangeAuthors);
    },
    componentDidMount: function() {
        CategoryStore.addChangeListener(this._onChangeCategories);
        AuthorStore.addChangeListener(this._onChangeAuthors);
        loadCategories();
        loadAuthors();
    }
});

module.exports.BookForm = BookForm;
&lt;/pre&gt;
&lt;p&gt;The above component listens for updates on both Category and Author store to update
when the authors (when an author is added or deleted) and the categories are changed (for example to implement the cascading dropdown
functionality), so the list of authors and the list of categories and subcategoreis are all stored in
the local state. The book that is edited is just passed as a property - actually, this is the only
property that this component needs to&amp;nbsp;work.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bookpanel-react-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id20"&gt;BookPanel.react.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, BookPanel is the last component we&amp;#8217;ll talk about. This is the central component
of the application - however we&amp;#8217;ll see that it is not very complex (since most user interaction
is performed in other components). This component just listens on changes in the BookStore state
and depending on the parameters either displays the &amp;quot;Loading&amp;quot; message or the table of books
(depending on the state of ajax calls that load the books). The other parameters like the
list of books, the ordering of the books etc are passed to the child&amp;nbsp;components.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookStore = require('../stores/BookStore').BookStore;
var BookActions = require('../actions/BookActions').BookActions;
var SearchPanel = require('./SearchPanel.react').SearchPanel;
var BookTable = require('./BookTable.react').BookTable;
var PagingPanel = require('./PagingPanel.react').PagingPanel;
var BookForm = require('./BookForm.react').BookForm;

var reloadBooks = require('../stores/BookStore').reloadBooks;

var BookPanel = React.createClass({
    getInitialState: function() {
        return BookStore.getState();
    },
    render: function() {
        return(
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    {
                        this.state.loading?
                        &amp;lt;div class='loading' &amp;gt;Loading...&amp;lt;/div&amp;gt;:
                        &amp;lt;div&amp;gt;
                            &amp;lt;SearchPanel query={this.state.query} &amp;gt;&amp;lt;/SearchPanel&amp;gt;
                            &amp;lt;BookTable books={this.state.books} ordering={this.state.ordering} /&amp;gt;
                            &amp;lt;PagingPanel page_size='5' total={this.state.total} page={this.state.page} /&amp;gt;
                        &amp;lt;/div&amp;gt;
                    }
                &amp;lt;/div&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    &amp;lt;BookForm
                        book={this.state.editingBook}
                    /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;br /&amp;gt;
            &amp;lt;/div&amp;gt;
        );
    },
    _onChange: function() {
        this.setState( BookStore.getState() );
    },
    componentWillUnmount: function() {
        BookStore.removeChangeListener(this._onChange);
    },
    componentDidMount: function() {
        BookStore.addChangeListener(this._onChange);
        reloadBooks();
    }
});

module.exports.BookPanel = BookPanel ;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="the-actions"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id21"&gt;The&amp;nbsp;Actions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All actions are rather simple components without other dependencies as we&amp;#8217;ve already discussed. They
just define &amp;quot;actions&amp;quot; (which are simple functions) that create the correct parameter object type and pass it
to the dispatcher. The only attribute that is required for this object is the &lt;tt class="docutils literal"&gt;actionType&lt;/tt&gt; that
should get a value from the constants. I won&amp;#8217;t go into any more detail about the actions &amp;#8212; please check
the source code and all your questions will be&amp;nbsp;resolved.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-stores"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id22"&gt;The&amp;nbsp;Stores&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First of all, all stores are defined through the following code that is already discussed in the previous&amp;nbsp;part:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var MessageStore = $.extend({}, EventEmitter.prototype, {
    getState: function() {
        return _state;
    },
    emitChange: function() {
        this.emit('change');
    },
    addChangeListener: function(callback) {
        this.on('change', callback);
    },
    removeChangeListener: function(callback) {
        this.removeListener('change', callback);
    }
});
&lt;/pre&gt;
&lt;p&gt;When the state of a store is changed its &lt;tt class="docutils literal"&gt;emitChange&lt;/tt&gt; function will be called (I mean
called manually from the code that actually changes the state and knows that it has
actually been changed - nothing will be called automatically). When &lt;tt class="docutils literal"&gt;emitChange&lt;/tt&gt; is called,
all the components that listen for changes for this component (that have called &lt;tt class="docutils literal"&gt;addChangeListener&lt;/tt&gt;
of the store with a callback)
will be notified (their callback will be called) and will use
&lt;tt class="docutils literal"&gt;getState&lt;/tt&gt; of the store to get its current state - after that, these components will set their own state
to re-render and display the changes to the&amp;nbsp;store.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s now discuss the four stores defined &amp;#8212; I will include only the parts of each file that are
actually interesting, for everything else &lt;em&gt;use the source Luke&lt;/em&gt;!&lt;/p&gt;
&lt;div class="section" id="id1"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id23"&gt;MessageStore.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A very simple store that goes together with MessagePanel and MessageActions. It just keeps a state with
the current message object and just changes this message when the MESSAGE_ADD message
type is dispatched. After changing the message, the listeners (only one in this case) will be notified to
update the displayed&amp;nbsp;message:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var _state = {
    message: {}
};

MessageStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.MESSAGE_ADD:
            _state.message = action.message;
            MessageStore.emitChange();
        break;
    }
    return true;
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="authorstore-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id24"&gt;AuthorStore.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Here we see that the local state has an array of the authors and a &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt; flag that
controls the state of the add author popup. For the &lt;tt class="docutils literal"&gt;AUTHOR_ADD&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;HIDE_ADD_AUTHOR&lt;/tt&gt;
cases of the dispatch we just change the state of this flag and emit the change; the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;
listens for changes to the &lt;tt class="docutils literal"&gt;AuthorStore&lt;/tt&gt; and will pass the &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;AuthorPanel&lt;/tt&gt;
as a property which in turn will pass it to &lt;tt class="docutils literal"&gt;AuthorDialog&lt;/tt&gt; and it will display the panel (or not)
depending on the value of that flag. This flag will also take a false value when the add author
ajax call&amp;nbsp;returns.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;showDialog&lt;/tt&gt; flag is not related to the actual data but is &lt;span class="caps"&gt;UI&lt;/span&gt;-related. This
is something that we should keep in mind when creating stores: Stores don&amp;#8217;t only contain the actual
data (like models in an &lt;span class="caps"&gt;MVC&lt;/span&gt; application) but they should also contain &lt;span class="caps"&gt;UI&lt;/span&gt; (controller/view in an &lt;span class="caps"&gt;MVC&lt;/span&gt;
architecture) related information since that is &lt;em&gt;also&lt;/em&gt; part of the&amp;nbsp;state!&lt;/p&gt;
&lt;p&gt;We can see that the ajax calls just issue the corresponding &lt;span class="caps"&gt;HTTP&lt;/span&gt; method to the &lt;tt class="docutils literal"&gt;authors_url&lt;/tt&gt; and
when they return the &lt;tt class="docutils literal"&gt;add_message_ok&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;add_message_error&lt;/tt&gt; methods of
&lt;tt class="docutils literal"&gt;MessageActions&lt;/tt&gt; will be called. These calls are in a different call stack so everything will work fine
(please remember the discussion about dispatches in different call stacks&amp;nbsp;before).&lt;/p&gt;
&lt;p&gt;Finally, on the success of &lt;tt class="docutils literal"&gt;_load_authors&lt;/tt&gt; the map array method is called to transform the returned data
as we want&amp;nbsp;it:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var $ = require('jquery');

var _state = {
    authors: [],
    showDialog: false
}

var _load_authors = function() {
    $.ajax({
        url: _props.authors_url,
        dataType: 'json',
        cache: false,
        success: function(data) {
            _state.authors = data.map(function(a){
                return {
                    id: a.id,
                    name: a.last_name+' '+a.first_name
                }
            });
            AuthorStore.emitChange();
        },
        error: function(xhr, status, err) {
            MessageActions.add_message_error(err.toString());
        }
    });
};

var _deleteAuthor = function(authorId) {
    $.ajax({
        url: _props.authors_url+authorId,
        method: 'DELETE',
        cache: false,
        success: function(data) {
            _load_authors();
            MessageActions.add_message_ok(&amp;quot;Author delete ok&amp;quot;);
            AuthorActions.delete_author_ok();
        },
        error: function(xhr, status, err) {
            MessageActions.add_message_error(err.toString());
        }
    });
};

var _addAuthor = function(author) {
    $.ajax({
        url: _props.authors_url,
        dataType: 'json',
        method: 'POST',
        data:author,
        cache: false,
        success: function(data) {
            MessageActions.add_message_ok(&amp;quot;Author add  ok&amp;quot;);
            _state.showDialog = false;
            _load_authors();
        },
        error: function(xhr, status, err) {
            MessageActions.add_message_error(err.toString());
        }
    });

};

AuthorStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.SHOW_ADD_AUTHOR:
            _state.showDialog = true;
            AuthorStore.emitChange();
        break;
        case BookConstants.HIDE_ADD_AUTHOR:
            _state.showDialog = false;
            AuthorStore.emitChange();
        break;
        case BookConstants.AUTHOR_ADD:
            _addAuthor(action.author);
        break;
        case BookConstants.AUTHOR_DELETE:
            _deleteAuthor(action.authorId);
        break;
    }
    return true;
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="categorystore-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id25"&gt;CategoryStore.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The CategoryStore has an interesting functionality concerning the load_subcategory
function. This function is called whenever a book is changed (so its category form field
may be changed and the subcategories may be reloaded based on this category) or is edited
(so the category is that of the new book and once again the subcategories may need to because
rerendered). It is important that we &lt;em&gt;actually&lt;/em&gt; pass the current category to the book to the
action. If for example we wanted to retrieve that from the state of the BookStore then we&amp;#8217;d
need to use the &lt;tt class="docutils literal"&gt;waitFor&lt;/tt&gt; functionality of the dispatcher so that the category of the
current book would be changed first then the load_category (that would read that value to
read the subcategoreis) would be called after&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;Also, another thing to notice here is that there&amp;#8217;s a simple subcat_cache that for each category
contains the subcategories of that category so that we won&amp;#8217;t do repeated ajax calls to reload
the subcategories each time the category is&amp;nbsp;changed.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var _state = {
    categories: [],
    subcategories: []
}

var _current_cat = ''
var _subcat_cache = []

var _load_categories = function() {
    $.ajax({
        url: _props.categories_url,
        dataType: 'json',
        cache: false,
        success: function(data) {
            _state.categories = data;
            CategoryStore.emitChange();
        },
        error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
        }
    });
};

var _load_subcategories = function(cat) {

    if(!cat) {
        _state.subcategories = [];
        CategoryStore.emitChange();
        return ;
    }
    if(_subcat_cache[cat]) {
        _state.subcategories = _subcat_cache[cat] ;
        CategoryStore.emitChange();
    }
    $.ajax({
        url: _props.subcategories_url+'?category='+cat,
        dataType: 'json',
        cache: false,
        success: function(data) {
            _state.subcategories = data;
            _subcat_cache[cat] = data;
            CategoryStore.emitChange();
        },
        error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
        }
    });
};

CategoryStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.BOOK_EDIT:
        case BookConstants.BOOK_CHANGE:
            _load_subcategories(action.book.category);
        break;
        case BookConstants.BOOK_EDIT_CANCEL:
            _state.subcategories = [];
            CategoryStore.emitChange();
        break;
    }
    return true;
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="bookstore-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id26"&gt;BookStore.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Here, beyond the book-related functionality we have also implemented the
&lt;span class="caps"&gt;URL&lt;/span&gt; updating. The getUrlParameter that returns the value of a &lt;span class="caps"&gt;URL&lt;/span&gt; parameter has been taken from
&lt;a class="reference external" href="http://stackoverflow.com/questions/19491336/get-url-parameter-jquery"&gt;http://stackoverflow.com/questions/19491336/get-url-parameter-jquery&lt;/a&gt;. Depending on the url parameters, we set some initial properties of
the local state and, on the other hand, when the search query, ordering or page are changed,
the &lt;tt class="docutils literal"&gt;_update_href&lt;/tt&gt; function is called to update the url parameters. This is not really related
to the flux architecture beyond the initialization of&amp;nbsp;state.&lt;/p&gt;
&lt;p&gt;Another thing to notice is that the when the &lt;tt class="docutils literal"&gt;_search&lt;/tt&gt; is executed whenever there&amp;#8217;s
a change in the list of books (query is updated, sorting is changed, page is changed or
when an author is deleted since the books that have that author should now display an
empty field). The setTimeout in the _search ajax return is to simulate a 400ms delay (in order for the &amp;quot;Loading&amp;quot; text to
be&amp;nbsp;visible).&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
function getUrlParameter(sParam) {
    var sPageURL = $(location).attr('hash');
    sPageURL = sPageURL.substr(1)
    var sURLVariables = sPageURL.split('&amp;amp;');
    for (var i = 0; i &amp;lt; sURLVariables.length; i++)  {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)  {
            return sParameterName[1];
        }
    }
}

var _page_init = 1*getUrlParameter('page');
if(!_page_init) _page_init = 1 ;
var _ordering_init = getUrlParameter('ordering');
if(!_ordering_init) _ordering_init = '' ;
var _query_init = getUrlParameter('query');
if(!_query_init) _query_init = ''

var _state = {
    loading: false,
    books: [],
    message:{},
    page: _page_init,
    total: 0,
    editingBook: {},
    query: _query_init,
    ordering: _ordering_init
}


var _search = function() {
    _state.loading = true;
    BookStore.emitChange();

    $.ajax({
        url: _props.url+'?search='+_state.query+&amp;quot;&amp;amp;ordering=&amp;quot;+_state.ordering+&amp;quot;&amp;amp;page=&amp;quot;+_state.page,
        dataType: 'json',
        cache: false,
        success: function(data) {
            // Simulate a small delay in server response
            setTimeout(function() {
                _state.books = data.results;
                _state.total = data.count;
                _state.loading = false;
                BookStore.emitChange();
            }, 400);
        },
        error: function(xhr, status, err) {
            _state.loading = false;
            MessageActions.add_message_error(err.toString());
            BookStore.emitChange();
        }
    });
};

var _reloadBooks = function() {
    _search('');
};


var _clearEditingBook = function() {
    _state.editingBook = {};
};

var _editBook = function(book) {
    _state.editingBook = book;
    BookStore.emitChange();
};

var _cancelEditBook = function() {
    _clearEditingBook();
    BookStore.emitChange();
};

var _update_href = function() {
    var hash = 'page='+_state.page;
    hash += '&amp;amp;ordering='+_state.ordering;
    hash += '&amp;amp;query='+_state.query;
    $(location).attr('hash', hash);
}

BookStore.dispatchToken = AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.BOOK_EDIT:
            _editBook(action.book);
        break;
        case BookConstants.BOOK_EDIT_CANCEL:
            _cancelEditBook();
        break;
        case BookConstants.BOOK_SAVE:
            _saveBook(action.book);
        break;
        case BookConstants.BOOK_SEARCH:
            _state.query = action.query
            _state.page = 1;
            _update_href();
            _search();
        break;
        case BookConstants.BOOK_DELETE:
            _deleteBook(action.bookId);
        break;
        case BookConstants.BOOK_CHANGE:
            _state.editingBook = action.book;
            BookStore.emitChange();
        break;
        case BookConstants.BOOK_PAGE:
            _state.page = action.page;
            _update_href();
            _search();
        break;
        case BookConstants.AUTHOR_DELETE_OK:
            _search();
        break;
        case BookConstants.BOOK_SORT:
            _state.page = 1;
            if(_state.ordering == action.field) {
                _state.ordering = '-'+_state.ordering
            } else {
                _state.ordering = action.field;
            }
            _update_href();
            _search();
        break;
    }
    return true;
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id27"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The application presented here has a number of techniques that will help
you when you actually try to create a more complex react flux application.
I hope that in the whole three part series I&amp;#8217;ve thoroughly explained the
flux architecture and how each
part of (actions, stores, components) it works. Also, I tried to cover
almost anything that somebody creating react/flux application
will need to use &amp;#8212; if you feel that something is not covered and
could be integrated to the authors/book application I&amp;#8217;d be happy
to research and implement&amp;nbsp;it!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 08 Sep 2015 12:55:00 +0300</pubDate><guid>tag:spapas.github.io,2015-09-08:2015/09/08/more-complex-react-flux-example/</guid><category>javascript</category><category>python</category><category>django</category><category>react</category><category>flux</category></item><item><title>django-rq redux: advanced techniques and tools</title><link>http://spapas.github.io/2015/09/01/django-rq-redux/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#displaying-your-task-progress" id="id2"&gt;Displaying your task&amp;nbsp;progress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#displaying-your-queue-statistics" id="id3"&gt;Displaying your queue&amp;nbsp;statistics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#making-sure-that-workers-for-your-queue-are-actually-running" id="id4"&gt;Making sure that workers for your queue are actually&amp;nbsp;running&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#checking-how-many-jobs-are-in-the-queue" id="id5"&gt;Checking how many jobs are in the&amp;nbsp;queue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#better-exception-handling" id="id6"&gt;Better exception&amp;nbsp;handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#multiple-django-apps-single-redis-db" id="id7"&gt;Multiple django-apps, single redis&amp;nbsp;db&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#low-level-debugging" id="id8"&gt;Low level&amp;nbsp;debugging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id9"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the &lt;a class="reference external" href="http://spapas.github.io/2015/01/27/async-tasks-with-django-rq/"&gt;previous django-rq article&lt;/a&gt;
we presented a quick introduction to asynchronous job queues and created a
small (but complete) project that used rq and django-rq to implement asynchronous
job queues in a django&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;In this article, we will present some more advanced techniques and tools
for improving the capabilities of our asynchronous tasks and
integrate them to the &lt;a class="reference external" href="https://github.com/spapas/django-test-rq"&gt;https://github.com/spapas/django-test-rq&lt;/a&gt; project (please
checkout tag django-rq-redux
&lt;tt class="docutils literal"&gt;git checkout &lt;span class="pre"&gt;django-rq-redux&lt;/span&gt;&lt;/tt&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="displaying-your-task-progress"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Displaying your task&amp;nbsp;progress&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes, especially for long-running tasks it is useful to let
the user (task initiator) know what is the status of each task he&amp;#8217;s started. For this,
I recommend creating a task-description model that will hold the required information for this
task with more or less the following fields (please also check &lt;tt class="docutils literal"&gt;LongTask&lt;/tt&gt; model of&amp;nbsp;django-test-rq):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class LongTask(models.Model):
  created_on = models.DateTimeField(auto_now_add=True)
  name = models.CharField(max_length=128, help_text='Enter a unique name for the task',)
  progress = models.PositiveIntegerField(default=0)
  result = models.CharField(max_length=128, blank=True, null=True)
&lt;/pre&gt;
&lt;p&gt;Now, when the view that starts the task is &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/tt&gt; ed, you&amp;#8217;ll first create
the &lt;tt class="docutils literal"&gt;LongTask&lt;/tt&gt; model instance with a result of &lt;tt class="docutils literal"&gt;'&lt;span class="caps"&gt;QUEUED&lt;/span&gt;'&lt;/tt&gt; and a progress
of 0 (and a name that identifies your task) and then you&amp;#8217;ll start the real task
asynchronously by passing the LongTask instance, something like this (also check
&lt;tt class="docutils literal"&gt;LongTaskCreateView&lt;/tt&gt;):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
long_task = LongTask.objects.create(...)
long_runnig_task.delay(long_task)
&lt;/pre&gt;
&lt;p&gt;In your asynchronous job, the first thing you&amp;#8217;ll need to do is to set its result
to &amp;#8216;&lt;span class="caps"&gt;STARTED&lt;/span&gt;&amp;#8217; and save it so that the user will immediately see when he&amp;#8217;s job is
actually started. Also, if you can estimate its progress, you can update its
progress value with the current value so that the user will know how close he
is to finishing. Finally, when the job finished (or if it throws an expectable
exception) you&amp;#8217;ll update its status accordingly. Here&amp;#8217;s an example of my
long_running_task that just waits for the specifid amount of&amp;nbsp;seconds:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;job('django-test-rq-low')
def long_runnig_task(task):
  job = get_current_job()
  task.job_id = job.get_id()

  task.result = 'STARTED'

  duration_in_second_persentages = task.duration*1.0 / 100
  for i in range(100):
      task.progress = i
      task.save()
      print task.progress
      time.sleep(duration_in_second_persentages)

  task.result = 'FINISHED'
  task.save()
  return task.result
&lt;/pre&gt;
&lt;p&gt;To have proper feedback I propose to have your task-description model instance
created by the view that starts the asynchronous task and &lt;em&gt;not&lt;/em&gt; by the
actual task! This is important since the worker may be full so the asynchronous
task will need a lot of time until is actually started (or maybe there are no
running workers - more on this later) and the user will not be able to see
his task instance anywhere (unless of course you provide him access to the actual task
queue but I don&amp;#8217;t recommend&amp;nbsp;this).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="displaying-your-queue-statistics"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Displaying your queue&amp;nbsp;statistics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;django-rq has a really nice dashboard with a lot of queue statistics (
instructions here
&lt;a class="reference external" href="https://github.com/ui/django-rq#queue-statistics"&gt;https://github.com/ui/django-rq#queue-statistics&lt;/a&gt; and also on django-test-rq
project) which I recommend to always&amp;nbsp;enable.&lt;/p&gt;
&lt;p&gt;Also, there&amp;#8217;s the individual use &lt;a class="reference external" href="https://github.com/brutasse/django-rq-dashboard"&gt;django-rq-dashboard&lt;/a&gt; project that could
be installed to display some more statistics, however the only extra
statistic that you can see throuh django-rq-dashboard is the status of
your scheduled jobs so I don&amp;#8217;t recommend installing it if you don&amp;#8217;t
use&amp;nbsp;scheduling.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="making-sure-that-workers-for-your-queue-are-actually-running"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Making sure that workers for your queue are actually&amp;nbsp;running&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the django-rq dashboard you can make sure that all queues
have at least one worker. However, sometimes workers fail, or
maybe you&amp;#8217;ve forgotten to start your workers or not configured
your application correctly (this happens to me all the time for
test/uat projects). So, for tasks that you want to display feedback
to the user, you can easily add a check to make sure that there are
active workers using the following&amp;nbsp;code:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from rq import Worker
import django_rq

redis_conn = django_rq.get_connection('default')
if len([
    x for x in Worker.all(connection=redis_conn)
        if 'django-test-rq-low' in x.queue_names()
]) == 0:
    # Error -- no workers
&lt;/pre&gt;
&lt;p&gt;With &lt;tt class="docutils literal"&gt;Worker.all()&lt;/tt&gt; you get all workers for a connection and the &lt;tt class="docutils literal"&gt;queue_names()&lt;/tt&gt;
method returns the names that each worker serves. So we check that we have at least one
worker for that&amp;nbsp;queue.&lt;/p&gt;
&lt;p&gt;This check can be added when the job is started and display a feedback error
to the user (check example in&amp;nbsp;django-test-rq).&lt;/p&gt;
&lt;p&gt;For quick tasks (for example sending emails etc) you should not display anything
to the user even if no workers are running (since the task &lt;em&gt;will&lt;/em&gt; be queued and
will be executed eventually when the workers are started) but instead send an email to the administrators
so that they will start the&amp;nbsp;workers.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="checking-how-many-jobs-are-in-the-queue"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Checking how many jobs are in the&amp;nbsp;queue&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To find out programatically how many jobs are actually in the queue (and display a message
if the queue has too many jobs etc) you&amp;#8217;ll need to use the &lt;tt class="docutils literal"&gt;Queue&lt;/tt&gt; class, something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from rq import Queue

redis_conn = django_rq.get_connection('default')
queue = Queue('django-test-rq-default', connection=redis_conn)
print queue.name
print len(queue.jobs)
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="better-exception-handling"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Better exception&amp;nbsp;handling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a job fails, rq will put it in a failed jobs queue and finish with it. You (as administrator)
won&amp;#8217;t get any feedback and the user (unless he has access to that failed jobs queue) won&amp;#8217;t be
able to do anything aboutt this&amp;nbsp;job.&lt;/p&gt;
&lt;p&gt;In almost all cases you can&amp;#8217;t rely only on this behavior but instead you have to
&lt;a class="reference external" href="http://python-rq.org/docs/exceptions/"&gt;install a custom exception handler&lt;/a&gt;. Using the custom exception handler you can
do whatever you want for each failed job. For instance, you can create a new instance
of a &lt;tt class="docutils literal"&gt;FailedTask&lt;/tt&gt; model which will have information about the failure and the
original task allow the user (or administrator) to restart the failed task after
he&amp;#8217;s fixed the error&amp;nbsp;conditions.&lt;/p&gt;
&lt;p&gt;Or, if you want to be informed when a job is failed, you can just send an email
to &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;ADMINS&lt;/span&gt;&lt;/tt&gt; and fall back to the default behavior to enqueue the failed task the
failed jobs queue (since job exception handlers can be&amp;nbsp;chained).&lt;/p&gt;
&lt;p&gt;A simple management command that starts a worker for a specific queue and installs
a custom exception handler&amp;nbsp;follows:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from django.conf import settings
from django.core.management.base import BaseCommand

import django_rq
from rq import Queue, Worker

def my_handler(job, *exc_info):
    print &amp;quot;FAILURE&amp;quot;
    print job
    print exc_info

class Command(BaseCommand):
    def handle(self, *args, **options):
        redis_conn = django_rq.get_connection('default')

        q = Queue(settings.DJANGO_TEST_RQ_LOW_QUEUE, connection=redis_conn)
        worker = Worker([q], exc_handler=my_handler, connection=redis_conn)
        worker.work()
&lt;/pre&gt;
&lt;p&gt;This handler is for demonstration purposes since it just prints a message to the console
(so please do not use&amp;nbsp;it)!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="multiple-django-apps-single-redis-db"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7"&gt;Multiple django-apps, single redis&amp;nbsp;db&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One thing to keep in mind is that the only thing that seperates the queues are
their name. If you have many django applications that define a &amp;quot;default&amp;quot; (or &amp;quot;low&amp;quot;, &amp;quot;hight&amp;quot; etc)
and they all use the &lt;em&gt;same&lt;/em&gt; redis database to store their queue, the workers
of each application won&amp;#8217;t know which jobs belong to them and they&amp;#8217;ll end up
dequeuing the wrong job types. This will lead to an exception or, if you
are really unlucky to a very nasty&amp;nbsp;bug!&lt;/p&gt;
&lt;p&gt;To avoid this, you can either use a different redis database (not database server)
for each of your apps or add a prefix with the name of your app to your queue&amp;nbsp;names:&lt;/p&gt;
&lt;p&gt;Each redis database server can host a number of databases that are identified
by a number (that&amp;#8217;s what the /0 you see in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;redis://127.0.0.1:6379/0&lt;/span&gt;&lt;/tt&gt; means)
and each one of them has a totally different keyspace. So, if you use /0 in an
application and /1 in another application, you&amp;#8217;ll have no problems. This solution
has the disadvantage that you need to be really careful to use different database
numbers for your projects and also the number of possible databases that redis
can use is limited by a configuration file (so if you reach the maximum you&amp;#8217;ll
need to also increase that&amp;nbsp;number)!&lt;/p&gt;
&lt;p&gt;Instead of this, you can avoid using the &amp;#8216;default&amp;#8217; queue, and use queues that
contain your application name in their name, for example, for the sample project
you could create something like &amp;#8216;django-test-rq-default&amp;#8217;, &amp;#8216;django-test-rq-low&amp;#8217;,
&amp;#8216;django-test-rq-high&amp;#8217; etc. You need to configure the extra queues by adding them
to the &lt;tt class="docutils literal"&gt;RQ_QUEUES&lt;/tt&gt; dictionary (check settings.py of django-test-rq) and then
put the jobs to these queues using for example the job decorator
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;job('django-test-rq-default')&lt;/span&gt;&lt;/tt&gt;)
and run your workers so that they will retrieve jobs from these queues
(&lt;tt class="docutils literal"&gt;python manage.py rqworker &lt;span class="pre"&gt;django-test-rq-default&lt;/span&gt;&lt;/tt&gt;) and not the
default one (which may contain jobs of other&amp;nbsp;applications).&lt;/p&gt;
&lt;p&gt;If you use the default queue, and because you&amp;#8217;ll need to use its name to
many places, I recommend to add a (f.i) &lt;tt class="docutils literal"&gt;QUEUE_NAME = &lt;span class="pre"&gt;'django-test-rq-default'&lt;/span&gt;&lt;/tt&gt;
setting and use this instead of just a string to be totally &lt;span class="caps"&gt;DRY&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 13/09/2015&lt;/strong&gt;: Please notice that using a &lt;em&gt;single&lt;/em&gt; redis database server
(either with multiple numeric databases or in the same database using a keyword
in keys to differentiate the apps) &lt;a class="reference external" href="https://redislabs.com/blog/benchmark-shared-vs-dedicated-redis-instances#.VfUl0xHtmko"&gt;is not recommended&lt;/a&gt; as commenter
Itamar Haber pointed out to&amp;nbsp;me!&lt;/p&gt;
&lt;p&gt;This is because for speed reasons redis uses a single thread to handle all requests
(regardless if they are in the same or different numerical databases), so all
resources may be used by a single, redis hungry, application and leave all others to&amp;nbsp;starve!&lt;/p&gt;
&lt;p&gt;Therefore, the recommended solution is to have a &lt;em&gt;different redis&lt;/em&gt; server for each different
application. This does not mean that you need to have different servers, just to run
different instances of redis binding to different &lt;span class="caps"&gt;IP&lt;/span&gt; ports. Redis uses very little
resourecs when it is idle (&lt;a class="reference external" href="http://redis.io/topics/faq"&gt;empty instance uses ~ 1 &lt;span class="caps"&gt;MB&lt;/span&gt; &lt;span class="caps"&gt;RAM&lt;/span&gt;&lt;/a&gt;) so you can run a lot
of instances in a single&amp;nbsp;server.&lt;/p&gt;
&lt;p&gt;Long story short, my proposal is to have a redis.conf &lt;em&gt;inside&lt;/em&gt; your application root tree
(next to manage.py and requirements.txt) which has the redis options for each
application. The options in redis.conf that need to be changed per application
is the port that this redis instance will bind (this port also needs to be passed to
django settings.py) and the pid filename if you daemonize redis &amp;#8212; I recommend using
a tool like &lt;a class="reference external" href="http://supervisord.org/"&gt;supervisord&lt;/a&gt; instead so that you won&amp;#8217;t need any daemonizing and pid files for
each&amp;nbsp;per-app-redis-instance!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="low-level-debugging"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id8"&gt;Low level&amp;nbsp;debugging&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this section I&amp;#8217;ll present some commands that you can issue to your redis
server using a simple telnet connection to get various info about your queues. You
probably will never need to issue these commands to actually debug, but they
will answer some of your (scientific) questions! In the following, &lt;tt class="docutils literal"&gt;&amp;gt;&lt;/tt&gt; is
things I type, &lt;tt class="docutils literal"&gt;#&lt;/tt&gt; are comments, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[...]&lt;/span&gt;&lt;/tt&gt; is more output and everything else is the output I&amp;nbsp;get:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt; telnet 127.0.0.1 6379

# You won't see anything at first but you'll be connected and you can try typing things

&amp;gt; INFO

$1020
redis_version:2.4.10
redis_git_sha1:00000000
# [...]
db0:keys=83,expires=2
db1:keys=26,expires=1 # My redis server has two databases

# Now you'll see what you type!

&amp;gt; SELECT 1
+ OK # Now queries will be issued to database 1
&amp;gt; SELECT 0
+ OK # Now queries will be issued to database 0

KEYS rq* # List all rq related queues
*25
$43
rq:job:1d7afa32-3f90-4502-912f-d58eaa049fb1
$43
rq:queue:django-test-rq-low
$43
[...]

&amp;gt; SMEMBERS rq:workers # See workers
*1
$26
rq:worker:SERAFEIM-PC.6892

&amp;gt; LRANGE rq:queue:django-test-rq-low 0 100 # Check queued jobs
*2
$36
def896f4-84cb-4833-be6a-54d917f05271
$36
53cb1367-2fb5-46b3-99b2-7680397203b9

&amp;gt; HGETALL rq:job:def896f4-84cb-4833-be6a-54d917f05271 # Get info about this job
*16
$6
status
$6
queued
$11
description
$57
tasks.tasks.long_runnig_task(&amp;lt;LongTask: LongTask object&amp;gt;)
$10
created_at
$20
2015-09-01T09:04:38Z
$7
timeout
$3
180
$6
origin
$18
django-test-rq-low
$11
enqueued_at
$20
2015-09-01T09:04:38Z
$4
data
$409
[...] # data is the pickled parameters passed to the job !

&amp;gt; HGET rq:job:def896f4-84cb-4833-be6a-54d917f05271 status # Get only status
$6
queued
&lt;/pre&gt;
&lt;p&gt;For more info on querying redis you can check the &lt;a class="reference external" href="http://redis.io/documentation"&gt;redis documentation&lt;/a&gt; and especially
&lt;a class="reference external" href="http://redis.io/topics/data-types"&gt;http://redis.io/topics/data-types&lt;/a&gt; and &lt;a class="reference external" href="http://redis.io/commands"&gt;http://redis.io/commands&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using some of the above techniques will help you in your asynchronous
task adventures with rq. I&amp;#8217;ll try to keep this article updated with
any new techniques or tools I find in the&amp;nbsp;future!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 01 Sep 2015 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-09-01:2015/09/01/django-rq-redux/</guid><category>django</category><category>python</category><category>tasks</category><category>jobs</category><category>rq</category><category>django-rq</category><category>asynchronous</category><category>scheduling</category><category>redis</category></item><item><title>A comprehensive React and Flux tutorial part 2: Flux</title><link>http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#flux-components" id="id2"&gt;Flux&amp;nbsp;components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-react-flux-version" id="id3"&gt;The react-flux version&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#main-js" id="id4"&gt;main.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#constants-js" id="id5"&gt;constants.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#actions-js" id="id6"&gt;actions.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#stores-js" id="id7"&gt;stores.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#components-js" id="id8"&gt;components.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#explaining-the-data-flow" id="id9"&gt;Explaining the data&amp;nbsp;flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-better-code-organization" id="id10"&gt;A better code&amp;nbsp;organization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id11"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the &lt;a class="reference external" href="http://spapas.github.io/2015/06/05/comprehensive-react-flux-tutorial/"&gt;first part of this series&lt;/a&gt; we implemented a
not-so-simple one page application with full &lt;span class="caps"&gt;CRUD&lt;/span&gt; capabilities. In this part, we will
modify that application to make it use the Flux architecture. The full source code can
be found at &lt;a class="reference external" href="https://github.com/spapas/react-tutorial"&gt;https://github.com/spapas/react-tutorial&lt;/a&gt; (tag name react-flux). In the
In &lt;a class="reference external" href="http://spapas.github.io/2015/09/08/more-complex-react-flux-example/"&gt;next part,&lt;/a&gt; we will create an even more complex application
using&amp;nbsp;react/flux!&lt;/p&gt;
&lt;p&gt;I recommend reading Facebook&amp;#8217;s &lt;a class="reference external" href="https://facebook.github.io/flux/docs/overview.html"&gt;Flux overview&lt;/a&gt; before reading this article &amp;#8212; please
read it even if you find some concepts difficult to grasp (I know I found it difficult
the first time I read it), I will try to explain everything here. Also,
because a rather large number of extra components will need to be created, we are
going to split our javascript code to different files using &lt;a class="reference external" href="http://browserify.org/"&gt;browserify&lt;/a&gt; - you can
learn &lt;a class="reference external" href="http://spapas.github.io/2015/05/27/using-browserify-watchify/"&gt;how to use browserify here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="flux-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Flux&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To implement the Flux architecture, an application needs to have at least a store and a&amp;nbsp;dispatcher.&lt;/p&gt;
&lt;p&gt;The store is the central place of truth for the application and the dispacher is the central
place of communications. The store should hold the
state (and any models/DAOs) of the application and notify the react components when this state is changed. Also,
the store will be notified by the dispatcher when an action happens (for example a button is clicked)
so that it will change the state. As a flow, we can think of something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
a ui action on a component (click, change, etc) -&amp;gt;
 ^   dispatcher is notified -&amp;gt;
 |   store is notified (by the dispacher)-&amp;gt;
 |   store state is changed -&amp;gt;
 └─  component is notified (by the store) and updated to reflect the change
&lt;/pre&gt;
&lt;p&gt;One thing to keep in mind is that although each flux application will have only one dispatcher, it may
have more stores, depending on the application&amp;#8217;s architecture and separation of concerns. If there are
more than store, all will be notified by the dispatcher and change their state (if needed of course).
The ui will pass the action type and any optional parameters to the dispatcher and the dispatcher
will notify all stores with these&amp;nbsp;parameters.&lt;/p&gt;
&lt;p&gt;An optional component in the Flux architecture is the Action. An action is a store related class that
acts as an intermediate between the ui and the dispatcher. So, when a user clicks a button, an action
will be called that will notify the dispatcher. As we will see we can just call the dispatcher directly
from the components ui, but calling it through the Action makes the calls more consistent and creates
an&amp;nbsp;interface.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-react-flux-version"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;The react-flux&amp;nbsp;version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since we are using browserify, we will include a single file in our html file with a &lt;tt class="docutils literal"&gt;&amp;lt;script&amp;gt;&lt;/tt&gt; tag
and everything else will be included through the &lt;tt class="docutils literal"&gt;require&lt;/tt&gt; function. We have the following packages
as requirements for&amp;nbsp;browserify:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;quot;dependencies&amp;quot;: {
  &amp;quot;flux&amp;quot;: &amp;quot;^2.0.3&amp;quot;,
  &amp;quot;jquery&amp;quot;: &amp;quot;^2.1.4&amp;quot;,
  &amp;quot;react&amp;quot;: &amp;quot;^0.13.3&amp;quot;,
  &amp;quot;reactify&amp;quot;: &amp;quot;^1.1.1&amp;quot;
}
&lt;/pre&gt;
&lt;p&gt;Also, in order to be able to use &lt;span class="caps"&gt;JSX&lt;/span&gt; with browserify, will use the &lt;a class="reference external" href="https://github.com/andreypopp/reactify"&gt;reactify&lt;/a&gt; transform. To apply it to
your project, change the &lt;tt class="docutils literal"&gt;scripts&lt;/tt&gt; of your &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; to:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;quot;scripts&amp;quot;: {
  &amp;quot;watch&amp;quot;: &amp;quot;watchify -v -d static/main.js -t reactify -o static/bundle.js&amp;quot;,
  &amp;quot;build&amp;quot;: &amp;quot;browserify static/main.js -t reactify  | uglifyjs -mc warnings=false &amp;gt; static/bundle.js&amp;quot;
},
&lt;/pre&gt;
&lt;div class="section" id="main-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id4"&gt;main.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; file will
just render the BookPanel component (the &lt;tt class="docutils literal"&gt;components.js&lt;/tt&gt; file contains the source for all React components) and call
the &lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; function from &lt;tt class="docutils literal"&gt;stores.js&lt;/tt&gt; that will reload all books from the &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var components = require('./components');
var stores = require('./stores');

React.render(&amp;lt;components.BookPanel url='/api/books/' /&amp;gt;, document.getElementById('content'));

stores.reloadBooks();
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="constants-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5"&gt;constants.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before going into more complex modules, let&amp;#8217;s present the &lt;tt class="docutils literal"&gt;constants.js&lt;/tt&gt; which just
exports some strings that will be passed to the dispatcher to differentiate between each
ui&amp;nbsp;action:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
module.exports = {
    BOOK_EDIT: 'BOOK_EDIT',
    BOOK_EDIT_CANCEL: 'BOOK_EDIT_CANCEL',
    BOOK_SAVE: 'BOOK_SAVE',
    BOOK_SEARCH: 'BOOK_SEARCH',
    BOOK_DELETE: 'BOOK_DELETE',
};
&lt;/pre&gt;
&lt;p&gt;As we can see, these constants are exported as a single object so when we do something like
&lt;tt class="docutils literal"&gt;var BookConstants = &lt;span class="pre"&gt;require('./constants')&lt;/span&gt;&lt;/tt&gt; we&amp;#8217;ll the be able to refer to each constant
through &lt;tt class="docutils literal"&gt;BookConstants.CONSTANT_NAME&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="actions-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;actions.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;actions.js&lt;/tt&gt; creates the dispatcher singleton and a BookActions object that defines the
actions for&amp;nbsp;books.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookConstants = require('./constants')
var Dispatcher = require('flux').Dispatcher;
var AppDispatcher = new Dispatcher();

var BookActions = {
    search: function(query) {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_SEARCH,
            query: query
        });
    },
    save: function(book) {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_SAVE,
            book: book
        });
    },
    edit: function(book) {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_EDIT,
            book: book
        });
    },
    edit_cancel: function() {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_EDIT_CANCEL
        });
    },
    delete: function(bookId) {
        AppDispatcher.dispatch({
            actionType: BookConstants.BOOK_DELETE,
            bookId: bookId
        });
    }
};

module.exports.BookActions = BookActions;
module.exports.AppDispatcher = AppDispatcher;
&lt;/pre&gt;
&lt;p&gt;As we can see, the BookActions is just a collection of methods that will
be called from the ui. Instead of calling BookActions.search() we could
just call the dispatch method with the correct parameter object (actionType
and optional parameter), both the BookActions object and the AppDispatcher
singleton are&amp;nbsp;exported.&lt;/p&gt;
&lt;p&gt;The dispatcher is imported from the flux requirement: It offers a functionality
to register callbacks for the various actions as we will see in the
next module. This is a rather simple class that we could implement ourselves
(each store passes a callback to the dispatcher that is called on the dispatch
method, passing actionType and any other parameters). The dispatcher also
offers a &lt;tt class="docutils literal"&gt;waitFor&lt;/tt&gt; method that can be used to ensure that the dispatch callback
for a store will be finished before another store&amp;#8217;s dispatch callback (
when the second store uses the state of the first store &amp;#8212; for example
when implementing a series of related dropdowns&amp;nbsp;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="stores-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;stores.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The next module we will discuss is the &lt;tt class="docutils literal"&gt;stores.js&lt;/tt&gt; that contains the
&lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; object.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var $ = require('jquery');
var EventEmitter = require('events').EventEmitter;
var AppDispatcher = require('./actions').AppDispatcher;
var BookConstants = require('./constants')

var _state = {
    books: [],
    message:&amp;quot;&amp;quot;,
    editingBook: null
}

var _props = {
    url: '/api/books/'
}

var _search = function(query) {
    $.ajax({
        url: _props.url+'?search='+query,
        dataType: 'json',
        cache: false,
        success: function(data) {
            _state.books = data;
            BookStore.emitChange();
        },
        error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
            _state.message = err.toString();
            BookStore.emitChange();
        }
    });
};

var _reloadBooks = function() {
    _search('');
};

var _deleteBook = function(bookId) {
    $.ajax({
        url: _props.url+bookId,
        method: 'DELETE',
        cache: false,
        success: function(data) {
            _state.message = &amp;quot;Successfully deleted book!&amp;quot;
            _clearEditingBook();
            _reloadBooks();
        },
        error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
            _state.message = err.toString();
            BookStore.emitChange();
        }
    });
};

var _saveBook = function(book) {
    if(book.id) {
        $.ajax({
            url: _props.url+book.id,
            dataType: 'json',
            method: 'PUT',
            data:book,
            cache: false,
            success: function(data) {
                _state.message = &amp;quot;Successfully updated book!&amp;quot;
                _clearEditingBook();
                _reloadBooks();
            },
            error: function(xhr, status, err) {
                _state.message = err.toString()
                BookStore.emitChange();
            }
        });
    } else {
        $.ajax({
            url: _props.url,
            dataType: 'json',
            method: 'POST',
            data:book,
            cache: false,
            success: function(data) {
                _state.message = &amp;quot;Successfully added book!&amp;quot;
                _clearEditingBook();
                _reloadBooks();
            },
            error: function(xhr, status, err) {
                _state.message = err.toString()
                BookStore.emitChange();
            }
        });
    }
};

var _clearEditingBook = function() {
    _state.editingBook = null;
};

var _editBook = function(book) {
    _state.editingBook = book;
    BookStore.emitChange();
};

var _cancelEditBook = function() {
    _clearEditingBook();
    BookStore.emitChange();
};

var BookStore = $.extend({}, EventEmitter.prototype, {
    getState: function() {
        return _state;
    },
    emitChange: function() {
        this.emit('change');
    },
    addChangeListener: function(callback) {
        this.on('change', callback);
    },
    removeChangeListener: function(callback) {
        this.removeListener('change', callback);
    }
});

AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case BookConstants.BOOK_EDIT:
            _editBook(action.book);
        break;
        case BookConstants.BOOK_EDIT_CANCEL:
            _cancelEditBook();
        break;
        case BookConstants.BOOK_SAVE:
            _saveBook(action.book);
        break;
        case BookConstants.BOOK_SEARCH:
            _search(action.query);
        break;
        case BookConstants.BOOK_DELETE:
            _deleteBook(action.bookId);
        break;
    }
    return true;
});

module.exports.BookStore = BookStore;
module.exports.reloadBooks = _reloadBooks;
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;stores.js&lt;/tt&gt; module exports only the &lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; object and the &lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; method (that could also be
called from inside the module since it&amp;#8217;s just called when the application is loaded to load the books for the
first time). All other objects/funtions are private to the&amp;nbsp;module.&lt;/p&gt;
&lt;p&gt;As we saw, the &lt;tt class="docutils literal"&gt;_state&lt;/tt&gt; objects keep the global state of the application which are the list of books, the book
that is edited right now and the result message for any update we are doing. The ajax methods are more or less
the same as the ones in the react-only version of the application. However, please notice that when the ajax methods
return and have to set the result, instead of setting the state of a React object they are just calling the
&lt;tt class="docutils literal"&gt;emitChange&lt;/tt&gt; method of the &lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; that will notify all react objects that &amp;quot;listen&amp;quot; to this store.
This is possible because the ajax (&lt;span class="caps"&gt;DAO&lt;/span&gt;) methods are in the same module with the store - if we wanted instead
to put them in different modules, we&amp;#8217;d just need to add another action (e.g &lt;tt class="docutils literal"&gt;ReloadBooks&lt;/tt&gt;) that would
be called when the ajax method returns &amp;#8212; this action would call the dispatcher which would in turn update the
state of the&amp;nbsp;store.&lt;/p&gt;
&lt;p&gt;We can see that we are importing the
AppDispatcher singleton and, depending on the action type we call the correct method that changes the state. So
when a BookActions action is called it will call the corresponding &lt;tt class="docutils literal"&gt;AppDispatcher.register&lt;/tt&gt; case branch which
will call the corresponding state-changing&amp;nbsp;function.&lt;/p&gt;
&lt;p&gt;The  BookStore extends the &lt;tt class="docutils literal"&gt;EventEmitter&lt;/tt&gt; object (so we need to &lt;tt class="docutils literal"&gt;require&lt;/tt&gt; the &lt;tt class="docutils literal"&gt;events&lt;/tt&gt; module) in order to
notify the React components when the state of the store is changed. Instead of using &lt;tt class="docutils literal"&gt;EventEmitter&lt;/tt&gt; we could
just implement the emit change logic ourselves by saving all the listener callbacks to an array and calling them
all when there&amp;#8217;s a state change (if we wanted to also add the &amp;#8216;change&amp;#8217; parameter to group the listener
callbacks we&amp;#8217;d just make the complex more complex, something not needed for our&amp;nbsp;case):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookStore = {
    listeners: [],
    getState: function() {
        return _state;
    },
    emitChange: function() {
        var i;
        for(i=0;i&amp;lt;this.listeners.length;i++) {
            this.listeners[i]();
        }
    },
    addChangeListener: function(callback) {
        this.listeners.push(callback);
    },
    removeChangeListener: function(callback) {
        this.listeners.splice(this.listeners.indexOf(callback), 1);
    }
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="components-js"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;components.js&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, the &lt;tt class="docutils literal"&gt;components.js&lt;/tt&gt; module contains all the React components. These are more
or less the same with the react-only version with three&amp;nbsp;differences:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;When something happens in the ui, the corresponding &lt;tt class="docutils literal"&gt;BookAction&lt;/tt&gt; action is called with the needed parameter &amp;#8212; no callbacks are passed between the&amp;nbsp;components&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; component registers with the &lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; in order to be notified when the state changes and just gets its state from the store &amp;#8212; these values are propagated to all other components through&amp;nbsp;properties&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;SearcchPanel&lt;/tt&gt; now hold their own temporary state instead of using the global state &amp;#8212; notice that when a book is edited this book will be propagated to the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; through the book property, however &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; needs to update its state through the &lt;tt class="docutils literal"&gt;componentWillReceiveProps&lt;/tt&gt; method.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
var React = require('react');
var BookStore = require('./stores').BookStore;
var BookActions = require('./actions').BookActions;

var BookTableRow = React.createClass({
    render: function() {
        return (
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;{this.props.book.id}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{this.props.book.title}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{this.props.book.category}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;a href='#' onClick={this.onClick}&amp;gt;Edit&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        );
    },
    onClick: function(e) {
        e.preventDefault();
        BookActions.edit(this.props.book);
    }
});

var BookTable = React.createClass({
    render: function() {
        var rows = [];
        this.props.books.forEach(function(book) {
            rows.push(&amp;lt;BookTableRow key={book.id} book={book} /&amp;gt;);
        });
        return (
            &amp;lt;table&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th&amp;gt;Id&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Category&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;Edit&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                &amp;lt;tbody&amp;gt;{rows}&amp;lt;/tbody&amp;gt;
            &amp;lt;/table&amp;gt;
        );
    }
});

var BookForm = React.createClass({
    getInitialState: function() {
        if (this.props.book) {
            return this.props.book;
        } else {
            return {};
        }
    },
    componentWillReceiveProps: function(props) {
        if (props.book) {
            this.setState(props.book);
        } else {
            this.replaceState({});
        }
    },
    render: function() {
        return(
            &amp;lt;form onSubmit={this.onSubmit}&amp;gt;
                &amp;lt;label forHtml='title'&amp;gt;Title&amp;lt;/label&amp;gt;&amp;lt;input ref='title' name='title' type='text' value={this.state.title} onChange={this.onFormChange} /&amp;gt;
                &amp;lt;label forHtml='category'&amp;gt;Category&amp;lt;/label&amp;gt;
                &amp;lt;select ref='category' name='category' value={this.state.category} onChange={this.onFormChange} &amp;gt;
                    &amp;lt;option value='CRIME' &amp;gt;Crime&amp;lt;/option&amp;gt;
                    &amp;lt;option value='HISTORY'&amp;gt;History&amp;lt;/option&amp;gt;
                    &amp;lt;option value='HORROR'&amp;gt;Horror&amp;lt;/option&amp;gt;
                    &amp;lt;option value='SCIFI'&amp;gt;SciFi&amp;lt;/option&amp;gt;
                &amp;lt;/select&amp;gt;
                &amp;lt;br /&amp;gt;
                &amp;lt;input type='submit' value={this.state.id?&amp;quot;Save (id = &amp;quot; +this.state.id+ &amp;quot;)&amp;quot;:&amp;quot;Add&amp;quot;} /&amp;gt;
                {this.state.id?&amp;lt;button onClick={this.onDeleteClick}&amp;gt;Delete&amp;lt;/button&amp;gt;:&amp;quot;&amp;quot;}
                {this.state.id?&amp;lt;button onClick={this.onCancelClick}&amp;gt;Cancel&amp;lt;/button&amp;gt;:&amp;quot;&amp;quot;}
                {this.props.message?&amp;lt;div&amp;gt;{this.props.message}&amp;lt;/div&amp;gt;:&amp;quot;&amp;quot;}
            &amp;lt;/form&amp;gt;
        );
    },
    onFormChange: function() {
        this.setState({
            title: React.findDOMNode(this.refs.title).value,
            category: React.findDOMNode(this.refs.category).value
        })
    },
    onSubmit: function(e) {
        e.preventDefault();
        BookActions.save(this.state)
    },
    onCancelClick: function(e) {
        e.preventDefault();
        BookActions.edit_cancel()
    },
    onDeleteClick: function(e) {
        e.preventDefault();
        BookActions.delete(this.state.id)
    }
});

var SearchPanel = React.createClass({
    getInitialState: function() {
        return {
            search: '',
        }
    },
    render: function() {
        return (
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                &amp;lt;div className=&amp;quot;one-fourth column&amp;quot;&amp;gt;
                    Filter: &amp;amp;nbsp;
                    &amp;lt;input ref='search' name='search' type='text' value={this.state.search} onChange={this.onSearchChange} /&amp;gt;
                    {this.state.search?&amp;lt;button onClick={this.onClearSearch} &amp;gt;x&amp;lt;/button&amp;gt;:''}
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    },
    onSearchChange: function() {
        var query = React.findDOMNode(this.refs.search).value;
        if (this.promise) {
            clearInterval(this.promise)
        }
        this.setState({
            search: query
        });
        this.promise = setTimeout(function () {
            BookActions.search(query);
        }.bind(this), 200);
    },
    onClearSearch: function() {
        this.setState({
            search: ''
        });
        BookActions.search('');
    }
});

var BookPanel = React.createClass({
    getInitialState: function() {
        return BookStore.getState();
    },
    render: function() {
        return(
            &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    &amp;lt;SearchPanel&amp;gt;&amp;lt;/SearchPanel&amp;gt;
                    &amp;lt;BookTable books={this.state.books} /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
                    &amp;lt;BookForm
                        book={this.state.editingBook}
                        message={this.state.message}
                    /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;br /&amp;gt;
            &amp;lt;/div&amp;gt;
        );
    },
    _onChange: function() {
        this.setState( BookStore.getState() );
    },
    componentWillUnmount: function() {
        BookStore.removeChangeListener(this._onChange);
    },
    componentDidMount: function() {
        BookStore.addChangeListener(this._onChange);
    }
});

module.exports.BookPanel = BookPanel ;
&lt;/pre&gt;
&lt;p&gt;Only the &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; is exported &amp;#8212; all other react components will be private to the&amp;nbsp;module.&lt;/p&gt;
&lt;p&gt;We can see that, beyond BookPanel, the code of all other components
are more or less the same. However, &lt;em&gt;not&lt;/em&gt; having to pass callbacks for state upddates
is a huge win for readability and&amp;nbsp;DRYness.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="explaining-the-data-flow"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Explaining the data&amp;nbsp;flow&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve added a bunch of console.log statements to see how the data/actions flow between
all the components when the &amp;quot;Edit&amp;quot; book is clicked. So, when we click &amp;quot;Edit&amp;quot; we see
the following messages to our&amp;nbsp;console:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
Inside BookTableRow.onClick
Inside BookActions.edit
Inside AppDispatcher.register
Inside AppDispatcher.register case BookConstants.BOOK_EDIT
Inside _editBook
Inside BookStore.emitChange
Inside BookPanel._onChange
Inside BookForm.componentWillReceiveProps
Inside BookForm.render
&lt;/pre&gt;
&lt;p&gt;First of all the &lt;tt class="docutils literal"&gt;onClick&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt; will be called (which is the onClick property of the
a href link) which will call &lt;tt class="docutils literal"&gt;BookActions.edit&lt;/tt&gt; and pass it the book of that specific row. The &lt;tt class="docutils literal"&gt;edit&lt;/tt&gt;
method will create a new dispatcher object by setting the &lt;tt class="docutils literal"&gt;actionType&lt;/tt&gt; and passing the &lt;tt class="docutils literal"&gt;book&lt;/tt&gt; and
pass it to &lt;tt class="docutils literal"&gt;AppDispatcher.register&lt;/tt&gt;. &lt;tt class="docutils literal"&gt;register&lt;/tt&gt; will go to the &lt;tt class="docutils literal"&gt;BookConstants.BOOK_EDIT&lt;/tt&gt; case branch
which will call the private &lt;tt class="docutils literal"&gt;_editBook&lt;/tt&gt; function. &lt;tt class="docutils literal"&gt;_editBook&lt;/tt&gt; will update the state of the store (by
setting the &lt;tt class="docutils literal"&gt;_state.editingBook&lt;/tt&gt; property and will call the &lt;tt class="docutils literal"&gt;BookStore.emitChange&lt;/tt&gt; method
which calls the dispatcher&amp;#8217;s emit method, so all listening components will update. We only have one
component that listens to this emit, &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; whose &lt;tt class="docutils literal"&gt;_onChange&lt;/tt&gt; method is called. This method
gets the application state from the &lt;tt class="docutils literal"&gt;BookStore&lt;/tt&gt; and updates its own state. Now, the state will be
propagated through properties - for example, for &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;, first its &lt;tt class="docutils literal"&gt;componentWillReceiveProps&lt;/tt&gt;
method will be called (with the new properties) and finally its &lt;tt class="docutils literal"&gt;render&lt;/tt&gt; method!&lt;/p&gt;
&lt;p&gt;So the full data flow is something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
user action/callback etc -&amp;gt;
  component calls action -&amp;gt;
    dispatcher informes stores -&amp;gt;
      stores set their state -&amp;gt;
        state holding components are notified and update their state -&amp;gt;
          all other components are updated through properties
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="a-better-code-organization"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id10"&gt;A better code&amp;nbsp;organization&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As you&amp;#8217;ve seen, I&amp;#8217;ve only created four javascript modules (components, stores, actions and constants)
and put them all in the same folder. I did this for clarity and to keep everything together since
our tutorial is a very small project. Facebook proposes a much better organization that what I did
as can be seen in the &lt;a class="reference external" href="https://facebook.github.io/flux/docs/todo-list.html"&gt;TodoMVC tutorial&lt;/a&gt;: Instead of putting everything to a single folder, create
a different foloder for each type of object: actions (for all your actions), components (for all
your React components), constants and stores and put inside the objects each in a different javascript
module, for example, the components folder should contain the following&amp;nbsp;files:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;BookTable.react.js&lt;/li&gt;
&lt;li&gt;BookTableRow.react.js&lt;/li&gt;
&lt;li&gt;BookForm.react.js&lt;/li&gt;
&lt;li&gt;BookPanel.react.js&lt;/li&gt;
&lt;li&gt;SearchPanel.react.js&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each one will export only the same-named React component and &lt;tt class="docutils literal"&gt;require&lt;/tt&gt; only the components that it&amp;nbsp;uses.&lt;/p&gt;
&lt;p&gt;If you want to see the code of this tutorial organized like this go to the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;react-flux-better-organization&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id11"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this two-part series we saw how we can create a full &lt;span class="caps"&gt;CRUD&lt;/span&gt; application with React.js and how can
we enable it with the Facebook proposed Flux architecture. Comparing the react-only with the react-flux
version we can see that we added a number of objects in the second version (dispatcher, store, actions, constants)
whose usefulness may not be obvious from our example. However, our created application (and especially
the better organized version) is war-ready and can easily fight any complexities that we throw to it!
Unfortunately, if we really wanted to show the usefulness of the Flux architecture we&amp;#8217;d need to create
a really complex application that won&amp;#8217;t be suitable for a&amp;nbsp;tutorial.&lt;/p&gt;
&lt;p&gt;However, we can already understand the obvious advantages of the React / Flux&amp;nbsp;architecture:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Components can easily be re-used by changing their properties - &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Easy to grasp (but a little complex) data flow between components and&amp;nbsp;stores&lt;/li&gt;
&lt;li&gt;Separation of concerns - react components for the view, stores to hold the state/models, dispatcher to handle the data&amp;nbsp;flow&lt;/li&gt;
&lt;li&gt;Really easy to test - all components are simple objects and can be easily created fom&amp;nbsp;tests&lt;/li&gt;
&lt;li&gt;Works well for complex architectures - one dispatcher, multiple stores/action collections, react components only interact with actions and get their state from&amp;nbsp;stores&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;ve tried to make the above as comprehensive as possible for the readers of these posts
(and also resolve some of my own questions). I have to mention again that although React/Flux may
seem complex at a first glance, when it is used in a complex architecture it will shine and
make everything much easier. Everything is debuggable and we can always understand what&amp;#8217;s
really going on! This is in contrast with more complex frameworks that do various hidden
stuff (two way data binding, magic in the &lt;span class="caps"&gt;REST&lt;/span&gt; etc) where, although it is easier to
create a simple app, moving to something more complex (and especially debugging it) is a real&amp;nbsp;nightmare!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Thu, 02 Jul 2015 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-07-02:2015/07/02/comprehensive-react-flux-tutorial-2/</guid><category>javascript</category><category>python</category><category>django</category><category>react</category><category>flux</category></item><item><title>A comprehensive React and Flux tutorial part 1: React</title><link>http://spapas.github.io/2015/06/05/comprehensive-react-flux-tutorial/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#our-project" id="id2"&gt;Our&amp;nbsp;project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-top-level-view-of-the-components" id="id3"&gt;A top-level view of the&amp;nbsp;components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-react-only-version" id="id4"&gt;The react-only version&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#searchpanel" id="id5"&gt;&lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#booktablerow" id="id6"&gt;&lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#booktable" id="id7"&gt;&lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#interlude-the-bind-function-method" id="id8"&gt;Interlude: The &lt;tt class="docutils literal"&gt;bind&lt;/tt&gt; function&amp;nbsp;method&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#bookform" id="id9"&gt;&lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#bookpanel" id="id10"&gt;&lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#component-methods" id="id11"&gt;Component&amp;nbsp;methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#non-ajax-object-methods" id="id12"&gt;Non-ajax object&amp;nbsp;methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ajax-object-methods" id="id13"&gt;Ajax object&amp;nbsp;methods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#local-state" id="id14"&gt;Local&amp;nbsp;state&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-form-validation" id="id15"&gt;Adding form&amp;nbsp;validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion-to-the-first-part" id="id16"&gt;Conclusion to the first&amp;nbsp;part&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update 15/12/2015&lt;/strong&gt;: Added some insights for form&amp;nbsp;validation.&lt;/p&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://facebook.github.io/react/"&gt;React&lt;/a&gt; is a rather new library from Facebook for building dynamic components for web pages.
It introduces a really simple, fresh approach to javascript user interface building. React
allows you to define composable and self-contained &lt;span class="caps"&gt;HTML&lt;/span&gt; components through Javascript (or a special syntax that compiles
to javascript named &lt;span class="caps"&gt;JSX&lt;/span&gt;) and that&amp;#8217;s all &amp;#8212; it doesn&amp;#8217;t force you into any specific
framework or architecture, you may use whatever you like. It&amp;#8217;s like writing pure
&lt;span class="caps"&gt;HTML&lt;/span&gt; but you have the advantage of using classes with all their advantages for your
components (self-contained, composable, reusable, mixins&amp;nbsp;etc).&lt;/p&gt;
&lt;p&gt;Although React components can be used however you like in your client-side applications, Facebook proposes a specific
architecture for the data flow of your events/data between the components called &lt;a class="reference external" href="https://facebook.github.io/flux/docs/overview.html"&gt;Flux&lt;/a&gt;.
It&amp;#8217;s important to keep in your mind that Flux is not a
specific framework but a way to organize the flow of events and data in your applicition.
Unfortunately, although Flux is a rather simple architecture it is a little difficult to understand
without a proper example (at least it was difficult for me to understand by reading the
Facebook documentation and some tutorials I&amp;nbsp;found).&lt;/p&gt;
&lt;p&gt;So, in this two-part tutorial we are going to build a (not-so-simple) single page &lt;span class="caps"&gt;CRUD&lt;/span&gt; application using
React and Flux. Two versions of the same application will be built and explained: One with
React (this part) only and one with React and Flux (part two). This will help us understand how
Flux architecture fits to our project and why it greatly improves the experience with&amp;nbsp;React.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: This is not an introduction to react. Before reading this you need
to be familiar with basic react usage, having read  at least the following three
pages from react&amp;nbsp;documentation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://facebook.github.io/react/docs/getting-started.html"&gt;https://facebook.github.io/react/docs/getting-started.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://facebook.github.io/react/docs/tutorial.html"&gt;https://facebook.github.io/react/docs/tutorial.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://facebook.github.io/react/docs/thinking-in-react.html"&gt;https://facebook.github.io/react/docs/thinking-in-react.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="our-project"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Our&amp;nbsp;project&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We are going to built a &lt;span class="caps"&gt;CRUD&lt;/span&gt; single-page application for editing views, let&amp;#8217;s take a look at how it&amp;nbsp;works:&lt;/p&gt;
&lt;img alt="Our project" src="/images/demo.gif" style="width: 780px;" /&gt;
&lt;p&gt;Our application will be seperated to two panels: In  the left one the user will be able to filter (search) for
a book and in the right panel she&amp;#8217;ll be able to add / edit / delete a book. Everything is supported by
a &lt;a class="reference external" href="http://www.django-rest-framework.org/"&gt;django-rest-framework&lt;/a&gt; implemented &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;. You can find the complete source code at
&lt;a class="reference external" href="https://github.com/spapas/react-tutorial"&gt;https://github.com/spapas/react-tutorial&lt;/a&gt;. I&amp;#8217;ve added a couple of git tags to the source history in
order to help us identify the differences between variou stages of the project (before and
after integrating the Flux&amp;nbsp;architecture).&lt;/p&gt;
&lt;p&gt;Django-rest-framework is used in the server-side back-end to create a really simple &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; - I won&amp;#8217;t
provide any tutorial details on that (unless somebody wants it !), however
you may either use the source code as is or create it from scratch using a different language/framework
or even just a static json file (however you won&amp;#8217;t see any changes to the data this&amp;nbsp;way).&lt;/p&gt;
&lt;p&gt;For styling (mainly to have a simple grid) we&amp;#8217;ll use &lt;a class="reference external" href="http://getskeleton.com/"&gt;skeleton&lt;/a&gt;. For the ajax calls and some utils we&amp;#8217;ll
use &lt;a class="reference external" href="https://jquery.com/"&gt;jquery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All client-side code will be contained in the file static/main.js. The placeholder &lt;span class="caps"&gt;HTML&lt;/span&gt; for our
application&amp;nbsp;is:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;lt;html&amp;gt;
  &amp;lt;!-- styling etc ignored --&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Hello, React!&amp;lt;/h1&amp;gt;
  &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;script src=&amp;quot;//fb.me/react-0.13.3.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;//fb.me/JSXTransformer-0.13.3.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;//code.jquery.com/jquery-2.1.3.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/jsx&amp;quot; src=&amp;quot;{% static 'main.js' %}&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;We are using the version 0.13.3 of react and the same version of the JSXTransformer to translate &lt;span class="caps"&gt;JSX&lt;/span&gt;
code to pure&amp;nbsp;javascript.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-top-level-view-of-the-components"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;A top-level view of the&amp;nbsp;components&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The following image shows how our components are&amp;nbsp;composed:&lt;/p&gt;
&lt;img alt="Our components" src="/images/components.png" style="width: 780px;" /&gt;
&lt;p&gt;So, the main component of our application is &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; which contains three&amp;nbsp;components:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt;: To allow search (filtering) books based on their&amp;nbsp;title/category&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;: To add/update/delete&amp;nbsp;books&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt;: To display all available books - each book is displayed in a &lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; is the only component having state &amp;#8212; all other components will be initialized by property
passing. The &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; element will be mounted to the &lt;tt class="docutils literal"&gt;#content&lt;/tt&gt; element when the page&amp;nbsp;loads.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-react-only-version"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;The react-only&amp;nbsp;version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first version, using only react (and not flux) will use &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; as a central information &lt;span class="caps"&gt;HUB&lt;/span&gt;.&lt;/p&gt;
&lt;div class="section" id="searchpanel"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5"&gt;&lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt; renders an input element with a value defined by the &lt;tt class="docutils literal"&gt;search&lt;/tt&gt; key of this component&amp;#8217;same
properties. When this is changed the &lt;tt class="docutils literal"&gt;onSearchChanged&lt;/tt&gt; method of the component will be called, which in turn,
retrieves the value of the input (using refs) and passes it to the properties &lt;tt class="docutils literal"&gt;onSearchChanged&lt;/tt&gt; callback function.
Finally, with the line &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{this.props.search?&amp;lt;button&lt;/span&gt; &lt;span class="pre"&gt;onClick={this.props.onClearSearch}&lt;/span&gt; &lt;span class="pre"&gt;&amp;gt;x&amp;lt;/button&amp;gt;:null}&lt;/span&gt;&lt;/tt&gt;
we check if the search property contains any text and if yes, we display a clear filter button that will call
properties onClearSearch&amp;nbsp;method:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var SearchPanel = React.createClass({
  render: function() {
    return (
      &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
        &amp;lt;div className=&amp;quot;one-fourth column&amp;quot;&amp;gt;
          Filter: &amp;amp;nbsp;
          &amp;lt;input ref='search' type='text' value={this.props.search} onChange={this.onSearchChanged} /&amp;gt;
          {this.props.search?&amp;lt;button onClick={this.props.onClearSearch} &amp;gt;x&amp;lt;/button&amp;gt;:null}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  },
  onSearchChanged: function() {
    var query = React.findDOMNode(this.refs.search).value;
    this.props.onSearchChanged(query);
  }
});
&lt;/pre&gt;
&lt;p&gt;So, this component has three&amp;nbsp;properties:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;search which is the text to display in the input&amp;nbsp;box&lt;/li&gt;
&lt;li&gt;onSearchChanged (callback) which is called when the contents of the input box are&amp;nbsp;changed&lt;/li&gt;
&lt;li&gt;onClearSearch (callback) which is called when the button is&amp;nbsp;pressed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that this component doesn&amp;#8217;t do anything - for all actions it uses the callbacks passed to it &amp;#8212;this
means that exactly the same component would easily be reused in a totally different application or could
be duplicated if we wanted to have a different search component for the book title and&amp;nbsp;category.&lt;/p&gt;
&lt;p&gt;Another thing to notice is that the local &lt;tt class="docutils literal"&gt;onSearchChanged&lt;/tt&gt; method is defined only to help us retrieve the
value of the input and use it to call the &lt;tt class="docutils literal"&gt;onSearchChanged&lt;/tt&gt; callback. Instead, we could just call the
passed
&lt;tt class="docutils literal"&gt;this.props.onSearchChanged&lt;/tt&gt; &amp;#8212; however to do this we&amp;#8217;d need a way to find the value of the input. This
could be done if we added a ref to the included &lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt; from the parent component, so
we&amp;#8217;d be able to use something like
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;React.findDOMNode(this.refs.searchPanel.refs.search).value&lt;/span&gt;&lt;/tt&gt; to find out the value of the input
(see that we use a ref to go to the searchPanel component and another ref to go to input&amp;nbsp;component).&lt;/p&gt;
&lt;p&gt;Both versions (getting the value directly from the child component or using the callback) could be used, however I
believe that the callback version defines a more clear interface since the parent component shouldn&amp;#8217;t need
to know the implementation details of its&amp;nbsp;children.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="booktablerow"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;&lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt; will render a table row by creating a simple table row that will contain the &lt;tt class="docutils literal"&gt;title&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;category&lt;/tt&gt; attributes of the passed book property and an edit link that will call the &lt;tt class="docutils literal"&gt;handleEditClickPanel&lt;/tt&gt;
property by passing the id of that&amp;nbsp;book:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookTableRow = React.createClass({
  render: function() {
    return (
      &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;{this.props.book.title}&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;{this.props.book.category}&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;a href='#' onClick={this.onClick}&amp;gt;Edit&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
    );
  },
  onClick: function(id) {
    this.props.handleEditClickPanel(this.props.book.id);
  }
});
&lt;/pre&gt;
&lt;p&gt;This component is used by &lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt; to render each one of the&amp;nbsp;books.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="booktable"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;&lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This component create the left-side table using an array of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;BookTableRow``s&lt;/span&gt; by passing it each one of the
books of the ``books&lt;/tt&gt; array property. The &lt;tt class="docutils literal"&gt;handleEditClickPanel&lt;/tt&gt;
property is retrieved from the parent of the component and passed as is to the&amp;nbsp;row.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookTable = React.createClass({
  render: function() {
    var rows = [];
    this.props.books.forEach(function(book) {
      rows.push(&amp;lt;BookTableRow key={book.id} book={book} handleEditClickPanel={this.props.handleEditClickPanel}  /&amp;gt;);
    }.bind(this));
    return (
      &amp;lt;table&amp;gt;
        &amp;lt;thead&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Category&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Edit&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;{rows}&amp;lt;/tbody&amp;gt;
      &amp;lt;/table&amp;gt;
    );
  }
});
&lt;/pre&gt;
&lt;p&gt;The key attribute is used by React to uniquely identify each component - we are using the id (primary key)
of each book. Before continuing with the other components, I&amp;#8217;d like to explain what is the purpose of that
strange &lt;tt class="docutils literal"&gt;bind&lt;/tt&gt; call!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="interlude-the-bind-function-method"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;Interlude: The &lt;tt class="docutils literal"&gt;bind&lt;/tt&gt; function&amp;nbsp;method&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind"&gt;bind&lt;/a&gt; is a method of the function javascript object, since in javascript &lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"&gt;functions are objects&lt;/a&gt;! This
method is useful for a number of things, however here we use it to set the &lt;tt class="docutils literal"&gt;this&lt;/tt&gt; keyword of the
anonymous function that is passed to foreach to the &lt;tt class="docutils literal"&gt;this&lt;/tt&gt; keyword of the &lt;tt class="docutils literal"&gt;render&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt;,
which will be the current BookTable&amp;nbsp;instance.&lt;/p&gt;
&lt;p&gt;To make things crystal: Since we are using an anonymous function to pass to &lt;tt class="docutils literal"&gt;forEach&lt;/tt&gt;, this anonymous
function won&amp;#8217;t have a &lt;tt class="docutils literal"&gt;this&lt;/tt&gt; keyword set to the current &lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt; object so we will get an error
that &lt;tt class="docutils literal"&gt;this.props&lt;/tt&gt; is undefined. That&amp;#8217;s why we use bind to set &lt;tt class="docutils literal"&gt;this&lt;/tt&gt; to the current &lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt;. If
instead of using the anonymous function we had created a &lt;tt class="docutils literal"&gt;createBookTableRow&lt;/tt&gt; method inside the
&lt;tt class="docutils literal"&gt;BookTable&lt;/tt&gt; object that returned the &lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt; and passed &lt;tt class="docutils literal"&gt;this.createBookTableRow&lt;/tt&gt; to
&lt;tt class="docutils literal"&gt;forEach&lt;/tt&gt;, we wouldn&amp;#8217;t have to use bind (notice that we&amp;#8217;d also need to make rows a class attribute
and  refer to it through &lt;tt class="docutils literal"&gt;this.rows&lt;/tt&gt; for this to&amp;nbsp;work).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bookform"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9"&gt;&lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; will create a form to either create a new book or update/delete an existing one. It has a &lt;tt class="docutils literal"&gt;book&lt;/tt&gt; object
property - when this object has an &lt;tt class="docutils literal"&gt;id&lt;/tt&gt; (so it is saved to the database) the update/delete/cancel buttons will be shown,
when it doesn&amp;#8217;t have an id the add button will be&amp;nbsp;shown.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookForm = React.createClass({
  render: function() {
    return(
      &amp;lt;form onSubmit={this.props.handleSubmitClick}&amp;gt;
        &amp;lt;label forHtml='title'&amp;gt;Title&amp;lt;/label&amp;gt;&amp;lt;input ref='title' name='title' type='text' value={this.props.book.title} onChange={this.onChange}/&amp;gt;
        &amp;lt;label forHtml='category'&amp;gt;Category&amp;lt;/label&amp;gt;
        &amp;lt;select ref='category' name='category' value={this.props.book.category} onChange={this.onChange} &amp;gt;
          &amp;lt;option value='CRIME' &amp;gt;Crime&amp;lt;/option&amp;gt;
          &amp;lt;option value='HISTORY'&amp;gt;History&amp;lt;/option&amp;gt;
          &amp;lt;option value='HORROR'&amp;gt;Horror&amp;lt;/option&amp;gt;
          &amp;lt;option value='SCIFI'&amp;gt;SciFi&amp;lt;/option&amp;gt;
        &amp;lt;/select&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;input type='submit' value={this.props.book.id?&amp;quot;Save (id = &amp;quot; +this.props.book.id+ &amp;quot;)&amp;quot;:&amp;quot;Add&amp;quot;} /&amp;gt;
        {this.props.book.id?&amp;lt;button onClick={this.props.handleDeleteClick}&amp;gt;Delete&amp;lt;/button&amp;gt;:null}
        {this.props.book.id?&amp;lt;button onClick={this.props.handleCancelClick}&amp;gt;Cancel&amp;lt;/button&amp;gt;:null}
        {this.props.message?&amp;lt;div&amp;gt;{this.props.message}&amp;lt;/div&amp;gt;:null}
      &amp;lt;/form&amp;gt;
    );
  },
  onChange: function() {
    var title = React.findDOMNode(this.refs.title).value;
    var category = React.findDOMNode(this.refs.category).value;
    this.props.handleChange(title, category);
  }
});
&lt;/pre&gt;
&lt;p&gt;As we can see, this component uses many properties &amp;#8212; most are passed callbacks functions for various&amp;nbsp;actions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;book&lt;/tt&gt;: This will either be a new book object (without and id) when adding one or an existing (from the database) book when updating&amp;nbsp;one.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;message&lt;/tt&gt;: To display the result of the last operation (save/delete) &amp;#8212; this is passed by the parent and probably it would be better if I had put it in a different component (and added styling&amp;nbsp;etc).&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleSubmitClick&lt;/tt&gt;: Will be called when the submit button is pressed to save the form (either by adding or&amp;nbsp;updating).&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleCancelClick&lt;/tt&gt;: Will be called when the cancel button is pressed &amp;#8212; we decide that we want actually want to edit a&amp;nbsp;book.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleDeleteClick&lt;/tt&gt;: Will be called when the delete button is&amp;nbsp;pressed.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt;: Will be called whenever the title or the category of the currently edited book is changed through the local onChange method. The onChange will retrieve that values of title and category and pass them to handleChange to do the state update. As already discussed, we could retrieve the values immediately from the parent but this creates a better interface to our&amp;nbsp;component.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="bookpanel"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10"&gt;&lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; component will contain all other components, will keep the global state
and will also act as a central communications &lt;span class="caps"&gt;HUB&lt;/span&gt; between the components and the server. Because
it is rather large class, I will explain it in three&amp;nbsp;parts:&lt;/p&gt;
&lt;div class="section" id="component-methods"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id11"&gt;Component&amp;nbsp;methods&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In the first part of &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;, its react component methods will be&amp;nbsp;presented:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var BookPanel = React.createClass({
  getInitialState: function() {
    return {
      books: [],
      editingBook: {
        title:&amp;quot;&amp;quot;,
        category:&amp;quot;&amp;quot;,
      },
      search:&amp;quot;&amp;quot;,
      message:&amp;quot;&amp;quot;
    };
  },
  render: function() {
    return(
      &amp;lt;div className=&amp;quot;row&amp;quot;&amp;gt;
        &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
          &amp;lt;SearchPanel
            search={this.state.search}
            onSearchChanged={this.onSearchChanged}
            onClearSearch={this.onClearSearch}
          /&amp;gt;
          &amp;lt;BookTable books={this.state.books} handleEditClickPanel={this.handleEditClickPanel} /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className=&amp;quot;one-half column&amp;quot;&amp;gt;
          &amp;lt;BookForm
            book={this.state.editingBook}
            message={this.state.message}
            handleChange={this.handleChange}
            handleSubmitClick={this.handleSubmitClick}
            handleCancelClick={this.handleCancelClick}
            handleDeleteClick={this.handleDeleteClick}
          /&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  },
  componentDidMount: function() {
    this.reloadBooks('');
  },
  // To be continued ...
&lt;/pre&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;getInitialState&lt;/tt&gt; is called the first time the component is created or mounted (attached to an &lt;span class="caps"&gt;HTML&lt;/span&gt; component in the page
and should return the initial values of the state - here we return an object with empty placeholders. &lt;tt class="docutils literal"&gt;componentDidMount&lt;/tt&gt;
will be called &lt;em&gt;after&lt;/em&gt; the component is mounted and that&amp;#8217;s the place we should do any initializationn &amp;#8212; here we call the
&lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; method (with an empty search string) to just retrieve all books. Finally, the &lt;tt class="docutils literal"&gt;render&lt;/tt&gt; method creates a
&lt;tt class="docutils literal"&gt;div&lt;/tt&gt; that will contain all other components and initializes their properties with either state variables or object methods
(these are the callbacks that were used in all other&amp;nbsp;components).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="non-ajax-object-methods"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id12"&gt;Non-ajax object&amp;nbsp;methods&lt;/a&gt;&lt;/h4&gt;
&lt;pre class="code literal-block"&gt;
// Continuing from above
onSearchChanged: function(query) {
  if (this.promise) {
    clearInterval(this.promise)
  }
  this.setState({
    search: query
  });
  this.promise = setTimeout(function () {
    this.reloadBooks(query);
  }.bind(this), 200);
},
onClearSearch: function() {
  this.setState({
    search: ''
  });
  this.reloadBooks('');
},
handleEditClickPanel: function(id) {
  var book = $.extend({}, this.state.books.filter(function(x) {
    return x.id == id;
  })[0] );

  this.setState({
    editingBook: book,
    message: ''
  });
},
handleChange: function(title, category) {
  this.setState({
    editingBook: {
      title: title,
      category: category,
      id: this.state.editingBook.id
    }
  });
},
handleCancelClick: function(e) {
  e.preventDefault();
  this.setState({
    editingBook: {}
  });
},
// to be continued ...
&lt;/pre&gt;
&lt;p&gt;All the above function change the &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; state so that the properties of the child components will
also be&amp;nbsp;updated:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;onSearchChanged&lt;/tt&gt; is called when the search text is changed. The behavior here is interesting: Instead of immediately reloading the books, we create a timeout to be executed after 200 ms (also notice the usage of the &lt;tt class="docutils literal"&gt;bind&lt;/tt&gt; function method to allow us call the &lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; method). If the user presses a key before these 200 ms, we cancel the previous timeout (using &lt;tt class="docutils literal"&gt;clearInterval&lt;/tt&gt;) and create a new one. This technique greatly reduces ajax calls to the server when the user is just typing something in the search box &amp;#8212; we could even increase the delay to reduce even more the ajax calls (but hurt the user experience a bit since the user will notice that his search results won&amp;#8217;t be updated&amp;nbsp;immediately).&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;onClearSearch&lt;/tt&gt; is called when the clear filter button is pressed and removes the search text and reloads all&amp;nbsp;books.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleEditClickPanel&lt;/tt&gt; is called when the edit link of a &lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt; is clicked. The book with the passed &lt;tt class="docutils literal"&gt;id&lt;/tt&gt; will be found (using filter) and then a clone of it will be created with (&lt;tt class="docutils literal"&gt;$.extend&lt;/tt&gt;) and will be used to set the &lt;tt class="docutils literal"&gt;editingBook&lt;/tt&gt; state attribute. If instead of the clone we passed the filtered book object we&amp;#8217;d see that when the title or category in the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; were changed they&amp;#8217;d also be changed in the &lt;tt class="docutils literal"&gt;BookTableRow&lt;/tt&gt;!&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt; just changes the state of the currently edited book based on the values passed (it does not modify the id of the&amp;nbsp;book)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleCancelClick&lt;/tt&gt; when the cancel editing is pressed we clear the &lt;tt class="docutils literal"&gt;editingBook&lt;/tt&gt; state attribute. Notice the &lt;tt class="docutils literal"&gt;e.preventDefault()&lt;/tt&gt; method that needs to be there in order to prevent the form from submitting since the form submitting would result in an undesirable full page&amp;nbsp;reload!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="ajax-object-methods"&gt;
&lt;h4&gt;&lt;a class="toc-backref" href="#id13"&gt;Ajax object&amp;nbsp;methods&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Finally, we need a buncch of object methods that use ajax calls to retrieve or update&amp;nbsp;books:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
  // Continuing from above
  reloadBooks: function(query) {
    $.ajax({
      url: this.props.url+'?search='+query,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({
          books: data
        });
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
        this.setState({
          message: err.toString(),
          search: query
        });
      }.bind(this)
    });
  },
  handleSubmitClick: function(e) {
    e.preventDefault();
    if(this.state.editingBook.id) {
      $.ajax({
        url: this.props.url+this.state.editingBook.id,
        dataType: 'json',
        method: 'PUT',
        data:this.state.editingBook,
        cache: false,
        success: function(data) {
          this.setState({
            message: &amp;quot;Successfully updated book!&amp;quot;
          });
          this.reloadBooks('');
        }.bind(this),
        error: function(xhr, status, err) {
          console.error(this.props.url, status, err.toString());
          this.setState({
            message: err.toString()
          });
        }.bind(this)
      });
    } else {
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        method: 'POST',
        data:this.state.editingBook,
        cache: false,
        success: function(data) {
          this.setState({
            message: &amp;quot;Successfully added book!&amp;quot;
          });
          this.reloadBooks('');
        }.bind(this),
        error: function(xhr, status, err) {
          console.error(this.props.url, status, err.toString());
          this.setState({
            message: err.toString()
          });
        }.bind(this)
      });
    }
    this.setState({
      editingBook: {}
    });
  },
  handleDeleteClick: function(e) {
  e.preventDefault();
  $.ajax({
    url: this.props.url+this.state.editingBook.id,
    method: 'DELETE',
    cache: false,
    success: function(data) {
      this.setState({
          message: &amp;quot;Successfully deleted book!&amp;quot;,
          editingBook: {}
      });
      this.reloadBooks('');
    }.bind(this),
    error: function(xhr, status, err) {
      console.error(this.props.url, status, err.toString());
      this.setState({
          message: err.toString()
      });
    }.bind(this)
    });
  },
});
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; will try to load the books using an ajax &lt;span class="caps"&gt;GET&lt;/span&gt; and pass its query parameter to filter the books (or get all books if query is an empty string). If the ajax call was successfull the state will be updated with the retrieved books and the search text (to clear the  search text when we reload because of a save/edit/delete) while if there was an error the state will be updated with the error message. The books will be returned as a json array of book&amp;nbsp;objects.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleSubmitClick&lt;/tt&gt; checks if the state&amp;#8217;s &lt;tt class="docutils literal"&gt;editingBook&lt;/tt&gt; has an id and  will do either a &lt;span class="caps"&gt;POST&lt;/span&gt; to create a new book or a &lt;span class="caps"&gt;PUT&lt;/span&gt; to update the existing one. Depending on the result of the operation will either reload books and clear the editingBook or set the error&amp;nbsp;message.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;handleDeleteClick&lt;/tt&gt; will do a &lt;span class="caps"&gt;DELETE&lt;/span&gt; to delete the state&amp;#8217;s &lt;tt class="docutils literal"&gt;editingBook&lt;/tt&gt; and clear&amp;nbsp;it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that all success and error functions above were binded to &lt;tt class="docutils literal"&gt;this&lt;/tt&gt; so that they could update the state of the current &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; object.&lt;/p&gt;
&lt;p&gt;After each succesfull ajax call we do a reload to the books to keep the state between server and client side consistent. We could
instead update the book array immediately before doing the ajax call - however this would increase complexity
(what should happen if an error happens at the ajax call) without improving the &lt;span class="caps"&gt;UX&lt;/span&gt; that much. A better solution
would be to add a loading css&amp;nbsp;animation.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="local-state"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id14"&gt;Local&amp;nbsp;state&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One thing to keep in mind is that there should only be one place of truth for the state and
that the state should be as high in the component hierarch as possible. All changes should
be propagated to thhe child components through properties.
That&amp;#8217;s the only way to be sure of the your data flow: When a change should happen
(either because of a user action or an asynchronous call e.g ajax or timeout) just
go to the state-holding component up in the hierarchy and change its state. Then the
changes will be propagated in a top-down fashion from that component to its&amp;nbsp;children.&lt;/p&gt;
&lt;p&gt;The above paragraph does not mean that the state should be contained in just a single
component! For example, let&amp;#8217;s say that we had an &lt;tt class="docutils literal"&gt;AuthorPanel&lt;/tt&gt; in the same web application
and both &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;AuthorPanel&lt;/tt&gt; would be contained in a &lt;tt class="docutils literal"&gt;BookAuthorPanel&lt;/tt&gt;.
In this case, we should keep a different state object for &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;AuthorPanel&lt;/tt&gt;,
we wouldn&amp;#8217;t need to combine them into a single object contained in the &lt;tt class="docutils literal"&gt;BookAuthorPanel&lt;/tt&gt;
since they are&amp;nbsp;unrelated!&lt;/p&gt;
&lt;p&gt;One decision that we took in &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; (and also to the &lt;tt class="docutils literal"&gt;SearchPanel&lt;/tt&gt; before) is to &lt;em&gt;not&lt;/em&gt; keep a local state for the
book that is edited but move it to &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;. This means that whenever the value of the &lt;tt class="docutils literal"&gt;title&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;category&lt;/tt&gt; is changed the parent
component will be informed (through &lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt;) so that it will change its state and the new values will
be passed down to &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; as properties so our changes will be reflected to the inputs. To make it more
clear, when you press a letter on the &lt;tt class="docutils literal"&gt;title&lt;/tt&gt; input:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the &lt;tt class="docutils literal"&gt;onChange&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; will be&amp;nbsp;called,&lt;/li&gt;
&lt;li&gt;it will get the values of both &lt;tt class="docutils literal"&gt;title&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;category&lt;/tt&gt; fields&lt;/li&gt;
&lt;li&gt;and call &lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt; with these&amp;nbsp;values.&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt; method of  &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; will update the &lt;tt class="docutils literal"&gt;editingBook&lt;/tt&gt; state&amp;nbsp;attribute,&lt;/li&gt;
&lt;li&gt;so the &lt;tt class="docutils literal"&gt;book&lt;/tt&gt; property of &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; will be also&amp;nbsp;updated&lt;/li&gt;
&lt;li&gt;and the new value of the &lt;tt class="docutils literal"&gt;title&lt;/tt&gt; will be displayed (since the components will be re-rendered due to the state&amp;nbsp;update)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conceptually, the above seems like a lot of work for just pressing a simple key! However, due to how react
is implemented (virtual &lt;span class="caps"&gt;DOM&lt;/span&gt;) it won&amp;#8217;t actually introduce any performance problems in our application.
If nevertheless we wanted to have a local state of the currently edited book inside the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; then we&amp;#8217;d need to use
&lt;tt class="docutils literal"&gt;state.book&lt;/tt&gt; and update the state using the &lt;tt class="docutils literal"&gt;componentWillReceiveProps&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;: If we
have a book to edit in the properties then copy it to the state or else just create an empty book. Also,
the &lt;tt class="docutils literal"&gt;onChange&lt;/tt&gt; method of the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; won&amp;#8217;t need to notify the parent component that there is a
state change (but only update the local state) and of course when the submit button is pressed the
current book should be passed to the parent component (to either save it or delete it) since it won&amp;#8217;t
know the book that is currently&amp;nbsp;edited.&lt;/p&gt;
&lt;p&gt;So we could either have a local state object for the edited book in the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; or
just save it as a property of the global state object in &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; &amp;#8212; both solutions are
correct. What wouldn&amp;#8217;t be correct is if we had two copies of the same information in both the
states of &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;, for example the book id that is&amp;nbsp;edited.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-form-validation"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id15"&gt;Adding form&amp;nbsp;validation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Commenter Nitish Kumar made a nice comment about how we could do some validating to our form&amp;nbsp;fields.&lt;/p&gt;
&lt;p&gt;First of all, this adds to the complexity of the application so maybe it would be better to do it in
the &lt;a class="reference external" href="http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/"&gt;flux-architectured version&lt;/a&gt;. However, it&amp;#8217;s not really difficult
to also have form validation using&amp;nbsp;react-only:&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what we&amp;nbsp;need:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A property (or properties) to pass the errors for each form field to the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; component&lt;/li&gt;
&lt;li&gt;A way to display the form errors if they exist in &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Execute an error handler when the form contents change and update the state if there&amp;#8217;s an&amp;nbsp;error&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As an example, I&amp;#8217;d like to check that the book title is not written in uppercase, so I will add another
attribute to the &lt;tt class="docutils literal"&gt;book&lt;/tt&gt; propery of &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; called &lt;tt class="docutils literal"&gt;titleError&lt;/tt&gt; and display it if it is defined,
something like&amp;nbsp;this:&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{this.props.book.titleError?&amp;lt;div&amp;gt;{this.props.book.titleError}&amp;lt;/div&amp;gt;:null}&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Now, the &lt;tt class="docutils literal"&gt;handleChange&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; should do the actual check and change the sate, so I&amp;#8217;m
changing it like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
handleChange: function(title, category) {
    var titleError = undefined;
    if(title.length &amp;gt; 1 &amp;amp;&amp;amp; title === title.toUpperCase()) {
        titleError='Please don\'t use only capital letters for book titles';
    }
    this.setState({
        editingBook: {
            title: title,
            titleError: titleError,
            category: category,
            id: this.state.editingBook.id
        }
    });
},
&lt;/pre&gt;
&lt;p&gt;So, the titleError attribute of editingBook will be defined only if there&amp;#8217;s an&amp;nbsp;error.&lt;/p&gt;
&lt;p&gt;Finally, we must remember to &lt;em&gt;not&lt;/em&gt; create/update the book if there&amp;#8217;s an error so
we add the following check to the &lt;tt class="docutils literal"&gt;handleSubmitClick&lt;/tt&gt; method:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
if(this.state.editingBook.titleError) {
    this.setState({
        message: &amp;quot;Please fix errors!&amp;quot;
    });
    return ;
}
&lt;/pre&gt;
&lt;p&gt;The above could be easily generalized for checks on multiple fields. I am not really fond
of doing the form validation in the &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt; component (I&amp;#8217;d prefer to do it on &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt;
or even better on the corresponding field - if it was a component) however this would mean that
I&amp;#8217;d need to keep a local state with the error to the &lt;tt class="docutils literal"&gt;BookForm&lt;/tt&gt; (please see the discussion of
the previous&amp;nbsp;paragraph).&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve added a new tag named &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;react-only-validation&lt;/span&gt;&lt;/tt&gt; to the &lt;a class="reference external" href="https://github.com/spapas/react-tutorial/"&gt;https://github.com/spapas/react-tutorial/&lt;/a&gt;
repository that contains the changes to have the&amp;nbsp;validation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-to-the-first-part"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id16"&gt;Conclusion to the first&amp;nbsp;part&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We just created a not-so-simple React single page application offering &lt;span class="caps"&gt;CRUD&lt;/span&gt; for an object.
This application of course could be improved by adding a pagination component to the table,
but I&amp;#8217;m going to leave that as an excersie to the reader: To do that, I propose to create
another component named &lt;tt class="docutils literal"&gt;TablePager&lt;/tt&gt; that would have two properties: &lt;tt class="docutils literal"&gt;currentPage&lt;/tt&gt; and
a &lt;tt class="docutils literal"&gt;changePageTo&lt;/tt&gt; callback. The &lt;tt class="docutils literal"&gt;currentPage&lt;/tt&gt; would also be needed to added to the global
state. When the &lt;tt class="docutils literal"&gt;changePageTo` is called by the ``TablePager&lt;/tt&gt; it would update the global
&lt;tt class="docutils literal"&gt;currentPage&lt;/tt&gt; and will do a &lt;tt class="docutils literal"&gt;reloadBooks&lt;/tt&gt; that will use the &lt;tt class="docutils literal"&gt;currentPage&lt;/tt&gt; to fetch
the correct&amp;nbsp;page.&lt;/p&gt;
&lt;p&gt;For application state keeping, we have selected to store all state attributes in &lt;tt class="docutils literal"&gt;BookPanel&lt;/tt&gt;,
for every state changing action we create a method that we pass in the child components
so that the children can call it when the state needs to be&amp;nbsp;updated.&lt;/p&gt;
&lt;p&gt;As we will see &lt;a class="reference external" href="http://spapas.github.io/2015/07/02/comprehensive-react-flux-tutorial-2/"&gt;in the next part&lt;/a&gt;, with Flux, Facebook proposes a design pattern for
where to store the state and how to update it. We&amp;#8217;ll see how to convert our React
application to also use Flux and find out how Flux will help us when developing
complex client-side&amp;nbsp;applications!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Fri, 05 Jun 2015 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-06-05:2015/06/05/comprehensive-react-flux-tutorial/</guid><category>javascript</category><category>python</category><category>django</category><category>react</category><category>flux</category></item><item><title>Using browserify and watchify to improve your client-side-javascript workflow</title><link>http://spapas.github.io/2015/05/27/using-browserify-watchify/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-problem" id="id1"&gt;The&amp;nbsp;problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-solution" id="id2"&gt;The&amp;nbsp;solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#installing-required-tools" id="id3"&gt;Installing required&amp;nbsp;tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#starting-your-node-js-project" id="id4"&gt;Starting your (node.js)&amp;nbsp;project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#running-browserify-for-the-first-time" id="id5"&gt;Running browserify for the first&amp;nbsp;time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-external-libraries" id="id6"&gt;Using external&amp;nbsp;libraries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introducing-watchify" id="id7"&gt;Introducing&amp;nbsp;watchify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-your-own-modules" id="id8"&gt;Creating your own&amp;nbsp;modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#uglifying-your-bundle" id="id9"&gt;Uglifying your&amp;nbsp;bundle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#the-client-side-javascript-workflow" id="id10"&gt;The client-side javascript&amp;nbsp;workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conlusion" id="id11"&gt;Conlusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;The&amp;nbsp;problem&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once upon a time, when people started using client-side code to their projects they (mainly
due to the lack of decent client-side libraries but also because of the &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Not_invented_here"&gt;&lt;span class="caps"&gt;NIH&lt;/span&gt; syndrome&lt;/a&gt;)
were just adding their own code in script nodes or .js files using &lt;tt class="docutils literal"&gt;document.getElementById&lt;/tt&gt; to manipulate
the &lt;span class="caps"&gt;DOM&lt;/span&gt; (good luck checking for all possible browser-edge cases)
and &lt;tt class="docutils literal"&gt;window.XMLHttpRequest&lt;/tt&gt; to try doing &lt;span class="caps"&gt;AJAX&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;After these dark-times, the
age of javascript-framework came: prototype, jquery, dojo. These were (and still are)
some great libraries (even &lt;span class="caps"&gt;NIH&lt;/span&gt;-sick people used them to handle browser incompatibilities):
You just downloaded the .js file with the framework, put it inside your project
static files and added it to your page with a script tag and then filled your client-side
code with funny $(&amp;#8216;#id&amp;#8217;)&amp;nbsp;symbols!&lt;/p&gt;
&lt;p&gt;Coming to the modern age in client-side development, the number of decent libraries has greatly increased
and instead of monolithic frameworks there are different libraries for different needs. So instead of
just downloading a single file and adding the script node for that file to your &lt;span class="caps"&gt;HTML&lt;/span&gt;, you need to
download the required javascript files, put them all in your static files directory and then micro-manage
the script nodes for each of your pages depending on which libraries each page needs! So if you want
to use (for example) moment.js to your client-side code you need to go to &lt;em&gt;all&lt;/em&gt; &lt;span class="caps"&gt;HTML&lt;/span&gt; pages that use that
specific client-side code and add a moment.js-script&amp;nbsp;element!&lt;/p&gt;
&lt;p&gt;As can be understood this leads to really ugly situations like people avoiding refactoring their code to use
external libraries, using a single-global module  with all their client side code, using &lt;span class="caps"&gt;CDN&lt;/span&gt; to avoid
downloading the javascript libraries and of course never upgrade their javascript&amp;nbsp;libraries!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;The&amp;nbsp;solution&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://browserify.org/"&gt;browserify&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/substack/watchify"&gt;watchify&lt;/a&gt; are two sister tools from the server-side-javascript (node.js and friends)
world that greatly improve your javascript workflow: Using them, you no longer need to micro-manage
your script tags but instead you just declare the libraries each of your client-side modules is
using - or you can even create your own reusable modules! Also, installing (or updating) javascript
libraries is as easy as running a single&amp;nbsp;command!&lt;/p&gt;
&lt;p&gt;How are they working? With browserify you create a single &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; for each of your &lt;span class="caps"&gt;HTML&lt;/span&gt;
pages and in it you declare its requirements using &lt;a class="reference external" href="https://github.com/substack/browserify-handbook#require"&gt;require&lt;/a&gt;. You&amp;#8217;ll then pass your &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt;
through browserify and it will create a single file (e.g &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt;) that contains all the requirements
(of course each requirement could have other requirements - they&amp;#8217;ll be automatically also
included in the resulting .js file). That&amp;#8217;s the &lt;em&gt;only&lt;/em&gt; file you need to put to the script tag of
your &lt;span class="caps"&gt;HTML&lt;/span&gt;! Using watchify, you can &lt;em&gt;watch&lt;/em&gt; your &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; for changes (the changes may also
be in the files included from main.js) and automatically generate the resulting &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt; so that
you&amp;#8217;ll just need to hit F5 to refresh and get the new&amp;nbsp;version!&lt;/p&gt;
&lt;p&gt;browserify not only concatenates your javascript libraries to a single bundle but can also transform
your coffesscript, typescript, jsx etc files to javascrpt and &lt;em&gt;then&lt;/em&gt; also add them to the bundle. This
is possible through a concept called transforms &amp;#8212; there are &lt;a class="reference external" href="https://github.com/substack/node-browserify/wiki/list-of-transforms"&gt;a lot of transforms&lt;/a&gt; that you can&amp;nbsp;use.&lt;/p&gt;
&lt;p&gt;Below, I will propose a really simple and generic workflow that should cover most of your javascript needs.
I should mention that I mainly develop django apps and my development machine is running windows, however you
can easily use exactly the  same workflow from any kind of server-side technology (ruby, python, javascript,
java, php or even static &lt;span class="caps"&gt;HTML&lt;/span&gt; pages!) or development machine (windows, linux, osx) - it&amp;#8217;s exactly the&amp;nbsp;same!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-required-tools"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Installing required&amp;nbsp;tools&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As already mentioned, you need two node.js tools. Just install them globally using npm (installing
node.js and npm is really easy - there&amp;#8217;s even &lt;a class="reference external" href="https://nodejs.org/download/"&gt;a package for windows&lt;/a&gt;):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install -g browserify watchify
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt; switch installs the packages globally so you can use the browserify and watchify commands from
your command prompt - after that entering &lt;tt class="docutils literal"&gt;browserify&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;watchify&lt;/tt&gt; from your command prompt should be&amp;nbsp;working.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="starting-your-node-js-project"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Starting your (node.js)&amp;nbsp;project&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Although you may already have a project structure, in order to use browserify you&amp;#8217;ll need to
create a node.js project (project from now on) that needs just two&amp;nbsp;things:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;a &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; that lists various options for your&amp;nbsp;project&lt;/li&gt;
&lt;li&gt;a &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; directory that contains the packages that your project&amp;nbsp;uses&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To create the &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; you can either copy paste a simple one or run &lt;tt class="docutils literal"&gt;npm init&lt;/tt&gt; inside
a folder of your project. After &lt;tt class="docutils literal"&gt;npm init&lt;/tt&gt; you&amp;#8217;ll need to answer a bunch of questions and then
a &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; will be created to the same folder. If you don&amp;#8217;t want to answer these questions
(most probably you only want to use node.js for browserify - instead you wouldn&amp;#8217;t be reading
this) then just put an empty json string &lt;tt class="docutils literal"&gt;{}&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I recommend adding &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; to the top-level folder of your version-controlled souce-code tree -
please put this file in your version control - the &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; directory will be be created
to the same directory with &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; and should be ignored by your version&amp;nbsp;control.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="running-browserify-for-the-first-time"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Running browserify for the first&amp;nbsp;time&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Not the time has come to create a &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; file. This could be put anywhere you like (based on your project structure) -
I&amp;#8221; suppose that &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; is inside the &lt;tt class="docutils literal"&gt;src/&lt;/tt&gt;  folder of your project.
Just put a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;console.log(&amp;quot;Hello,&lt;/span&gt; world&amp;quot;)&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;main.js&lt;/tt&gt; for now. To test that everything is working,&amp;nbsp;run:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
browserify src/main.js
&lt;/pre&gt;
&lt;p&gt;You should see some minified-js gibberish to your console (something like &lt;tt class="docutils literal"&gt;(function &lt;span class="pre"&gt;e(t,n,r){function&lt;/span&gt; &lt;span class="pre"&gt;s(o,u){if(!n[o]){if(!t[o]){var&lt;/span&gt; a=typeof &lt;span class="pre"&gt;...)&lt;/span&gt;&lt;/tt&gt;
) which means that everything works fine. Now, create a &lt;tt class="docutils literal"&gt;dist&lt;/tt&gt; directory which would contain your bundle files and&amp;nbsp;run&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
browserify src/main.js -o dist/bundle.js
&lt;/pre&gt;
&lt;p&gt;the -o switch will put the the same minified-js gibberish output to the  &lt;tt class="docutils literal"&gt;dist/bundle.js&lt;/tt&gt; file instead of stdout.
Finally, include a script element with that file to your &lt;span class="caps"&gt;HTML&lt;/span&gt; and you
should see &amp;quot;Hello, world&amp;quot; to your javascript console when opening the &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;file!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-external-libraries"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Using external&amp;nbsp;libraries&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To use a library from your main.js you need to install it and get a reference to it through require. Let&amp;#8217;s try to use &lt;a class="reference external" href="http://momentjs.com/"&gt;moment.js&lt;/a&gt;:
To install the library&amp;nbsp;run&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install moment --save
&lt;/pre&gt;
&lt;p&gt;This will create a moment directory inside node_modules that will contain the moment.js library. It will also add a
dependency to your &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; (that&amp;#8217;s what the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--save&lt;/span&gt;&lt;/tt&gt; switch does), something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;quot;dependencies&amp;quot;: {
  &amp;quot;moment&amp;quot;: &amp;quot;^2.10.3&amp;quot;
}
&lt;/pre&gt;
&lt;p&gt;Whenever you install more client-side libraries they&amp;#8217;ll be saved there. When you want to re-install everything (for instance
when you clone your project) you can just do&amp;nbsp;a&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install
&lt;/pre&gt;
&lt;p&gt;and all dependencies of &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; will be installed in &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; (that&amp;#8217;s why &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; should not be&amp;nbsp;tracked).&lt;/p&gt;
&lt;p&gt;After you&amp;#8217;ve installed moment.js to your project change &lt;tt class="docutils literal"&gt;src/main.js&lt;/tt&gt; to:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
moment = require('moment')
console.log(moment() );
&lt;/pre&gt;
&lt;p&gt;and rerun &lt;tt class="docutils literal"&gt;browserify src/main.js &lt;span class="pre"&gt;-o&lt;/span&gt; dist/bundle.js&lt;/tt&gt;. When you reload your &lt;span class="caps"&gt;HTML&lt;/span&gt; you&amp;#8217;ll see the that you are able to use
moment - all this without changing your &lt;span class="caps"&gt;HTML&lt;/span&gt;!!!&lt;/p&gt;
&lt;p&gt;As you can understand, in order to use a library with browserify, this library must support it by having an npm package. The nice thing is that
most libraries already support it &amp;#8212; let&amp;#8217;s try for another example to use &lt;a class="reference external" href="http://underscorejs.org/"&gt;underscore.js&lt;/a&gt; and (for some reason) we need version underscore 1.7&amp;nbsp;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install underscore&amp;#64;1.7--save
&lt;/pre&gt;
&lt;p&gt;you&amp;#8217;ll se that your package.json dependencies will also contain underscore.js&amp;nbsp;1.7:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
{
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;moment&amp;quot;: &amp;quot;^2.10.3&amp;quot;,
    &amp;quot;underscore&amp;quot;: &amp;quot;^1.7.0&amp;quot;
  }
}
&lt;/pre&gt;
&lt;p&gt;If you want to upgrade underscore to the latest version run&amp;nbsp;a:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install underscore --upgrade --save
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll see that your &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt; will contan the latest version of&amp;nbsp;underscore.js.&lt;/p&gt;
&lt;p&gt;Finally, let&amp;#8217;s change our &lt;tt class="docutils literal"&gt;src/man.js&lt;/tt&gt; to use&amp;nbsp;underscore:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
moment = require('moment')
_ = require('underscore')

_([1,2,3]).map(function(x) {
  console.log(x+1);
});
&lt;/pre&gt;
&lt;p&gt;After you create your bundle you should se 2 3 4 in your&amp;nbsp;console!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="introducing-watchify"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7"&gt;Introducing&amp;nbsp;watchify&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running browserify &lt;em&gt;every&lt;/em&gt; time you change your js files to create the &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt; feels
like doing repetitive work - this is where wachify comes to the rescue; watchify is a
tool that watches your source code and dependencies and when a change is detected it will
recreate the bundle&amp;nbsp;automagically!&lt;/p&gt;
&lt;p&gt;To run it, you can&amp;nbsp;use:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
watchify src/main.js -o dist/bundle.js -v
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll see something like: &lt;tt class="docutils literal"&gt;155544 bytes written to dist/bundle.js (0.57 seconds)&lt;/tt&gt; &amp;#8212; try
changing main.js and you&amp;#8217;ll see that bundle.js will also be&amp;nbsp;re-written!&lt;/p&gt;
&lt;p&gt;Some things to keep in mind with watchify&amp;nbsp;usage:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The -v flag outputs the verbose text (or else you won&amp;#8217;t se any postive messages) - I like using it to be sure that everything is&amp;nbsp;ok.&lt;/li&gt;
&lt;li&gt;You need to use the -o flag with watchify &amp;#8212; you can&amp;#8217;t output to stdout(we&amp;#8217;ll see that this will change our workflow for production a bit&amp;nbsp;later)&lt;/li&gt;
&lt;li&gt;watchify takes the same parameters with browserify &amp;#8212; so if you do any transformations with browserify you can also do them with&amp;nbsp;watchify&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the following, I&amp;#8217;ll assume that you are running the &lt;tt class="docutils literal"&gt;watchify src/main.js &lt;span class="pre"&gt;-o&lt;/span&gt; dist/bundle.js &lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; so your bundles will
always be re-created when changes are&amp;nbsp;found.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-your-own-modules"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id8"&gt;Creating your own&amp;nbsp;modules&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using browserify we can create our own modules and &lt;em&gt;require&lt;/em&gt; them in other modules using the &lt;tt class="docutils literal"&gt;module.exports&lt;/tt&gt; mechanism!&lt;/p&gt;
&lt;p&gt;Creating a module is really simple: In a normal javascript file either assign directly to module.exports or
include all local objects you want to be visible as an attribute to &lt;tt class="docutils literal"&gt;module.exports&lt;/tt&gt; &amp;#8212; everything
else will be private to the&amp;nbsp;module.&lt;/p&gt;
&lt;p&gt;As an example, let&amp;#8217;s create an &lt;tt class="docutils literal"&gt;src/modules&lt;/tt&gt; folder and put a file module1.js inside it, containing the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var variable = 'variable'
var variable2 = 'variable2'
var funct = function(x) {
  return x+1;
}
var funct2 = function(x) {
  return x+1;
}

module.exports['variable'] = variable
module.exports['funct'] = funct
&lt;/pre&gt;
&lt;p&gt;As you see, although we&amp;#8217;ve defined a number of things in that module, only the variable and funct attributes
of module.exports will be visible when the module is used. To use the module, change main.js like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
module1 = require('./modules/module1')
console.log(module1.funct(9))
&lt;/pre&gt;
&lt;p&gt;When you refresh your &lt;span class="caps"&gt;HTML&lt;/span&gt; you&amp;#8217;ll see 10 in the console. So, require will return the &lt;tt class="docutils literal"&gt;module.exports&lt;/tt&gt; objects
of each module. It will either search in your project&amp;#8217;s &lt;tt class="docutils literal"&gt;node_modules&lt;/tt&gt; (when you use just the modfule name,
for example &lt;tt class="docutils literal"&gt;moment&lt;/tt&gt;, or locally (when you start a path with either &lt;tt class="docutils literal"&gt;./&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;../&lt;/tt&gt; &amp;#8212; in our case we required
the module &lt;tt class="docutils literal"&gt;module1.js&lt;/tt&gt; from the folder &lt;tt class="docutils literal"&gt;modules&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;As a final example, we&amp;#8217;ll create another module that is used by module1: Create a file named &lt;tt class="docutils literal"&gt;module2.js&lt;/tt&gt; inside the
&lt;tt class="docutils literal"&gt;modules&lt;/tt&gt; folder and the following&amp;nbsp;contents:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
var funct = function(x) {
    return x+1;
}

module.exports = funct
&lt;/pre&gt;
&lt;p&gt;After that, change &lt;tt class="docutils literal"&gt;module1.js&lt;/tt&gt; to&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
module2 = require('./module2')

var variable = 'variable'
var funct = function(x) {
    return module2(x)+1;
}

module.exports['variable'] = variable
module.exports['funct'] = funct
&lt;/pre&gt;
&lt;p&gt;So &lt;tt class="docutils literal"&gt;module1&lt;/tt&gt; will import the &lt;tt class="docutils literal"&gt;module2&lt;/tt&gt; module (from the same directory) and call it (since a function is assignedd to module.exports).
When you refresh your &lt;span class="caps"&gt;HTML&lt;/span&gt; you should see&amp;nbsp;11!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="uglifying-your-bundle"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Uglifying your&amp;nbsp;bundle&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If had taken a look at the file size of your &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt; when you&amp;#8217;d included moment.js or underscore.js you&amp;#8217;d see
that the file size has been greatly increased. Take a peek at &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt; and you&amp;#8217;ll see why: The contents of the module files
will be concatenated as they are, without any changes! This may be nice for development / debugging, however for production
we&amp;#8217;d like our bundle.js to be minified &amp;#8212; or uglyfied as it&amp;#8217;s being said in the javascript&amp;nbsp;world.&lt;/p&gt;
&lt;p&gt;To help us with this, uglifying we&amp;#8217;ll use &lt;a class="reference external" href="https://www.npmjs.com/package/uglify-js"&gt;uglify-js&lt;/a&gt;. First of all, please install it&amp;nbsp;globally&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
npm install uglify-js -g
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll be able to use the &lt;tt class="docutils literal"&gt;uglifyjs&lt;/tt&gt; command to uglify your bundles! To use the &lt;tt class="docutils literal"&gt;uglifyjs&lt;/tt&gt; command for your &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt;
try&amp;nbsp;this&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
uglifyjs dist\bundle.js  &amp;gt; dist\bundle.min.js
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll see the size of the bundle.min.js greatly reduced! To achieve even better minification (and code mangling as an added
bonus) you could pass the -mc options to&amp;nbsp;uglify:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
uglifyjs dist\bundle.js -mc &amp;gt; dist\bundle.min.js
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll see an even smaller&amp;nbsp;bundle.min.js!&lt;/p&gt;
&lt;p&gt;As a final step, we can combine the output of browserify and uglify to a single command using a&amp;nbsp;pipe:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
browserify src/main.js | uglifyjs -mc &amp;gt; dist/bundle.js
&lt;/pre&gt;
&lt;p&gt;this will create the uglified bundle.js! Using the pipe to output to uglifyjs is not possible
with watchify since watchify cannot output to stdout &amp;#8212; however, as we&amp;#8217;ll see in the next section
this is not a real&amp;nbsp;problem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-client-side-javascript-workflow"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id10"&gt;The client-side javascript&amp;nbsp;workflow&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The proposed client-side javascript workflow uses two commands, one for the development and one
for creating the production&amp;nbsp;bundle.&lt;/p&gt;
&lt;p&gt;For the development, we&amp;#8217;ll use watchify since we need to immediately re-create the bundle when a
javascript source file is changed and we don&amp;#8217;t want any&amp;nbsp;uglification:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
watchify src/main.js -o dist/bundle.js -v
&lt;/pre&gt;
&lt;p&gt;For creating our production bundle, we&amp;#8217;ll use browserify and&amp;nbsp;uglify:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
browserify src/main.js  | uglifyjs -mc warnings=false &amp;gt; dist/bundle.js
&lt;/pre&gt;
&lt;p&gt;(i&amp;#8217;ve added warnings=false to uglfiyjs to suppress&amp;nbsp;warnings).&lt;/p&gt;
&lt;p&gt;The above two commands can either be put to batch files or added to your existing workflow (for example
as &lt;a class="reference external" href="http://www.fabfile.org/"&gt;fabric&lt;/a&gt; commands if you use fabric). However, since we already have a javascrpt project (i.e a &lt;tt class="docutils literal"&gt;package.json&lt;/tt&gt;)
we can use that to run these commands. Just add a &lt;tt class="docutils literal"&gt;scripts&lt;/tt&gt; section to your package.json like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
{
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;moment&amp;quot;: &amp;quot;^2.10.3&amp;quot;,
    &amp;quot;underscore&amp;quot;: &amp;quot;^1.8.3&amp;quot;
  },
  &amp;quot;scripts&amp;quot;: {
    &amp;quot;watch&amp;quot;: &amp;quot;watchify src/main.js -o dist/bundle.js -v&amp;quot;,
    &amp;quot;build&amp;quot;: &amp;quot;browserify src/main.js  | uglifyjs -mc warnings=false &amp;gt; dist/bundle.js&amp;quot;
  }
}
&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;ll be able to run &lt;tt class="docutils literal"&gt;npm run watch&lt;/tt&gt; to start watchifying for changes and &lt;tt class="docutils literal"&gt;npm run build&lt;/tt&gt; to
create your production&amp;nbsp;bundle!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conlusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id11"&gt;Conlusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the above we saw two (three if we include uglifyjs) javascript tools that will greatly improve our
javascript workflow. Using these we can easily &lt;em&gt;require&lt;/em&gt; (import) external javascript libraries to
our project without any micromanagement of script tags in html files. We also can seperate our own
client-side code to self-contained modules that will only export interfaces and not pollute the global
namespace. The resulting production client-side javascript file will be output minimized and ready to
be used by the users&amp;#8217;&amp;nbsp;browsers.&lt;/p&gt;
&lt;p&gt;All the above are possible with minimal changes to our code and development&amp;nbsp;workflow:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;create a package.json and install your&amp;nbsp;dependencies&lt;/li&gt;
&lt;li&gt;require the external libraries (instead of using them off the global&amp;nbsp;namespace)&lt;/li&gt;
&lt;li&gt;define your module&amp;#8217;s interace through module.exports (instead of polluting the global&amp;nbsp;namespace)&lt;/li&gt;
&lt;li&gt;change your client javascript files to &lt;tt class="docutils literal"&gt;bundle.js&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;run &lt;tt class="docutils literal"&gt;npm run watch&lt;/tt&gt; when developing and &lt;tt class="docutils literal"&gt;npm run build&lt;/tt&gt; before&amp;nbsp;deploying&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Wed, 27 May 2015 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-05-27:2015/05/27/using-browserify-watchify/</guid><category>javascript</category><category>browserify</category><category>node</category><category>npm</category><category>watchify</category><category>generic</category><category>uglify</category></item><item><title>Show 404 page on django when DEBUG=True</title><link>http://spapas.github.io/2015/04/29/django-show-404-page/</link><description>&lt;p&gt;The default 404 error page on django can be &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.8/topics/http/views/#the-http404-exception"&gt;easily overriden&lt;/a&gt; by adding
a template named &lt;tt class="docutils literal"&gt;404.html&lt;/tt&gt; to the top level directory of your templates.
However, on your development environment you&amp;#8217;ll never be able to see this
template because when &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEBUG&lt;/span&gt;=True&lt;/tt&gt; django will render the debug not found
page to help you debug your url&amp;nbsp;configuration.&lt;/p&gt;
&lt;p&gt;If you want to display that page in your development environment you can always
change the &lt;span class="caps"&gt;DEBUG&lt;/span&gt; setting to False, however there&amp;#8217;s a better way: Add a url
pattern for django&amp;#8217;s default 404 view - just  add the following to your &lt;tt class="docutils literal"&gt;urls.py&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;django.views.defaults&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c"&gt;# Other url patterns ...&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^404/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaults&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_not_found&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&amp;#8217;ll then be able to see your 404 page by visiting the defined &lt;span class="caps"&gt;URL&lt;/span&gt;!&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Wed, 29 Apr 2015 10:20:00 +0300</pubDate><guid>tag:spapas.github.io,2015-04-29:2015/04/29/django-show-404-page/</guid><category>django</category><category>debug</category><category>404</category><category>error</category><category>python</category></item><item><title>Calling the REST API of Pusher from python</title><link>http://spapas.github.io/2015/02/06/python-pusher-rest/</link><description>&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://pusher.com/"&gt;Pusher&lt;/a&gt; is one of the best real time frameworks right now. Using it you can add real time
events in your projects without the need to configure and use &lt;span class="caps"&gt;HTTP&lt;/span&gt; servers that support
real-time events in your environment. I used it recently in a project and it worked really
good, having a very simple &lt;span class="caps"&gt;API&lt;/span&gt; and a nice interface for debugging your&amp;nbsp;requests.&lt;/p&gt;
&lt;p&gt;The only problem I&amp;#8217;ve found was that the &lt;a class="reference external" href="https://github.com/pusher/pusher_client_python"&gt;Pusher python &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; misses some features that
the APIs for other languages have, specifically finding out the users on a presence&amp;nbsp;channel.&lt;/p&gt;
&lt;p&gt;Pusher supports real-time events through the use of &amp;quot;channels&amp;quot;. Each pusher client will
subscribe to a channel and receive messages that are sent to that channel. A special kind
of channel are presence channels which keep a list of their subscribers. You can query the
&lt;a class="reference external" href="https://pusher.com/docs/rest_api"&gt;Pusher &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; (or f.e the Pusher Javascript &lt;span class="caps"&gt;API&lt;/span&gt;) to find out the names of the users
in a presence channel - however this is &lt;em&gt;not&lt;/em&gt; currently possible with the python &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Unfortuanately, calling the Pusher &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; is &lt;em&gt;not&lt;/em&gt; so easy, since it needs a complicated
singining of each request, so I&amp;#8217;ve written this post to help developers that need to call
this &lt;span class="caps"&gt;API&lt;/span&gt; from python (to get the users of a presence channel or for any other method the
&lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&amp;nbsp;supports).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="signing-the-request"&gt;
&lt;h2&gt;Signing the&amp;nbsp;request&lt;/h2&gt;
&lt;p&gt;Quoting from the &lt;a class="reference external" href="https://pusher.com/docs/rest_api"&gt;Pusher &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;, to sign a request we need a signature,&amp;nbsp;which:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The signature is a &lt;span class="caps"&gt;HMAC&lt;/span&gt; &lt;span class="caps"&gt;SHA256&lt;/span&gt; hex digest. This is generated by signing a string made up of the following components concatenated with newline characters&amp;nbsp;\n:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The uppercase request method (e.g. &lt;span class="caps"&gt;POST&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;The request path (e.g.&amp;nbsp;/some/resource)&lt;/li&gt;
&lt;li&gt;The query parameters sorted by key, with keys converted to lowercase, then joined as in the query string. Note that the string must not be url escaped (e.g. given the keys auth_key: foo, Name: Something else, you get auth_key=foo&amp;amp;name=Something&amp;nbsp;else)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, we need to create a string and then sign it using our Pusher api_key and secret. To help with this, we create a &lt;tt class="docutils literal"&gt;Token&lt;/tt&gt;
class which will be initialzed with out pusher key/secret and correctly sign a&amp;nbsp;string:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It uses the &lt;tt class="docutils literal"&gt;hmac&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;hashlib&lt;/tt&gt; python&amp;nbsp;modules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="generating-the-complete-query-string"&gt;
&lt;h2&gt;Generating the complete query&amp;nbsp;string&lt;/h2&gt;
&lt;p&gt;We can now create a function that will sign a request using an instance of the above&amp;nbsp;token:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_signed_query_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_key&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;params_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;params_list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;{0}={1}&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;query_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;amp;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;sign_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query_string&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;query_string&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;amp;auth_signature=&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sign_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;query_string&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;create_signed_query_string&lt;/tt&gt; receives an instance of a &lt;tt class="docutils literal"&gt;Token&lt;/tt&gt;, the path that we want to request
without the server part (for example &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/apps/33/users/my-channel&lt;/span&gt;&lt;/tt&gt;)  and a dictionary of
request parameters. It then adds three extra fields to the request parameters (&lt;tt class="docutils literal"&gt;auth_key, auth_timestamp, auth_version&lt;/tt&gt;)
and creates a list of these parameters in the &lt;tt class="docutils literal"&gt;key=value&lt;/tt&gt; form, where the keys are alphabetically sorted.
After that it joins the above &lt;tt class="docutils literal"&gt;key=value&lt;/tt&gt; parameters using &lt;tt class="docutils literal"&gt;&amp;amp;&lt;/tt&gt; to create the &lt;tt class="docutils literal"&gt;query_string&lt;/tt&gt; and then it creates the string to be signed (&lt;tt class="docutils literal"&gt;sign_data&lt;/tt&gt;)
by concatenating the &lt;span class="caps"&gt;HTTP&lt;/span&gt; methdo (&lt;span class="caps"&gt;GET&lt;/span&gt;) with the path and the &lt;tt class="docutils literal"&gt;query_string&lt;/tt&gt;. Finally, it appends the signing result as an extra
query parameter named (&lt;tt class="docutils literal"&gt;auth_signature&lt;/tt&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="requesting-the-users-of-the-presence-channel"&gt;
&lt;h2&gt;Requesting the users of the presence&amp;nbsp;channel&lt;/h2&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;create_signed_query_string&lt;/tt&gt; can now be used to get the users of a presence channel like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;partial_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;&amp;#39;/apps/{0}/channels/{1}/users&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_signed_query_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;full_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;http://api.pusherapp.com/{0}?{1}&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;get_users&lt;/tt&gt; function will generate the path of the pusher &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; (using
our pusher app_id and channel name) and initialize a signing &lt;tt class="docutils literal"&gt;Token&lt;/tt&gt; using
the pusher key and secret. It will then pass the previous to &lt;tt class="docutils literal"&gt;create_signed_query_string&lt;/tt&gt;
to generate the complete &lt;tt class="docutils literal"&gt;query_string&lt;/tt&gt; and generate the &lt;tt class="docutils literal"&gt;full_path&lt;/tt&gt; to which
a simple &lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;GET&lt;/span&gt; request is issued. The result will be a &lt;span class="caps"&gt;JSON&lt;/span&gt; list of the users in the
presence&amp;nbsp;channel.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="complete-example"&gt;
&lt;h2&gt;Complete&amp;nbsp;example&lt;/h2&gt;
&lt;p&gt;A complete example of getting the presence users of a channel is the&amp;nbsp;following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;hashlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;hmac&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;app_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;pusher_app_id&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;pusher_key&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;pusher_secret&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;pusher_presence_channel&amp;#39;&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_signed_query_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_key&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;auth_version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;params_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;params_list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;{0}={1}&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;query_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;amp;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;sign_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query_string&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;query_string&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;amp;auth_signature=&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sign_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;query_string&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;partial_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;&amp;#39;/apps/{0}/channels/{1}/users&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;create_signed_query_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;full_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;http://api.pusherapp.com/{0}?{1}&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;partial_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With the above we are able to not only easily get the users of a Pusher presence
channel in python but to also call any method we want from the Pusher &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; by implementing a function
similar to  &lt;tt class="docutils literal"&gt;get_users&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Fri, 06 Feb 2015 12:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-02-06:2015/02/06/python-pusher-rest/</guid><category>pusher</category><category>python</category><category>rest</category></item><item><title>Asynchronous tasks in django with django-rq</title><link>http://spapas.github.io/2015/01/27/async-tasks-with-django-rq/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#job-queues-in-python" id="id2"&gt;Job queues in&amp;nbsp;python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#django-test-rq" id="id3"&gt;django-test-rq&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#models-py" id="id4"&gt;models.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#forms-py" id="id5"&gt;forms.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#views-py" id="id6"&gt;views.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#tasks-py" id="id7"&gt;tasks.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#settings-py" id="id8"&gt;settings.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#running-the-project" id="id9"&gt;Running the&amp;nbsp;project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#rqworker-and-rqscheduler" id="id10"&gt;rqworker and rqscheduler&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#for-development" id="id11"&gt;For&amp;nbsp;development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#for-production" id="id12"&gt;For&amp;nbsp;production&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id13"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update 01/09/15&lt;/strong&gt;: I&amp;#8217;ve written a new post about rq and django with some
&lt;a class="reference external" href="http://spapas.github.io/2015/09/01/django-rq-redux/"&gt;more advanced techniques&lt;/a&gt;&amp;nbsp;!&lt;/p&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Job queuing (asynchronous tasks) is a common requirement for non-trivial django projects. Whenever an operation
can take more than half a second it should be put to a job queue in order to be run asynchronously by a
seperate worker. This is really important since the response to a user request needs to be immediate
or else the users will experience laggy behavior and start complaining!
Even for fairly quick tasks (like sending email through an &lt;span class="caps"&gt;SMTP&lt;/span&gt; server) you need to use an asynchronous task
if you care about your users since
the time required for such a task is not really&amp;nbsp;limited.&lt;/p&gt;
&lt;p&gt;Using job queues is involved not only for the developers of the application (who need to create the
asynchronous tasks and give feedback to the users when the&amp;#8217;ve finished since they can&amp;#8217;t use the normal
&lt;span class="caps"&gt;HTTP&lt;/span&gt; response) and but also for the administrators, since, in order to support job queues at least two
more componets will be&amp;nbsp;needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;One job queue that will store the jobs to be executed next in a first in first queue. This could be the normal database of the project however it&amp;#8217;s not recommended for performance reasons and most of thetimes it is a specific component called &amp;quot;Message&amp;nbsp;Broker&amp;quot;&lt;/li&gt;
&lt;li&gt;One (or more) workers that will monitor the job queue and when there is work to do they will dequeue and execute&amp;nbsp;it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These can all run in the same server but if it gets saturated they can easily be seperated (even more work for&amp;nbsp;administrators).&lt;/p&gt;
&lt;p&gt;Beyond job queuing, another relative requirement for many projects is to schedule a task to be run in the future
(similar to the &lt;tt class="docutils literal"&gt;at&lt;/tt&gt; unix command) or at specific time intervals (similar to the &lt;tt class="docutils literal"&gt;cron&lt;/tt&gt; unix command). For
instance, if a user is registered today we may need to check after one or two days if he&amp;#8217;s logged in and used our application -
if he hasn&amp;#8217;t then probably he&amp;#8217;s having problems and we can call him to help him. Also, we could check every night
to see if any users that have registered to our application don&amp;#8217;t have activated their account through email activation
and delete these accounts. Scheduled tasks should be also run by the workers mentioned&amp;nbsp;above.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="job-queues-in-python"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Job queues in&amp;nbsp;python&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most known application for using job queues in python is &lt;a class="reference external" href="http://www.celeryproject.org/"&gt;celery&lt;/a&gt; which is a really great project that supports
many brokers,  integrates nicely
with python/django (but can be used even with other languages) and has
many more features (most of them are only useful on really big, enterprise projects). I&amp;#8217;ve already used
it in a previous application, however, because celery is really complex I found it rather difficult to
configure it successfully and I never was perfectly sure that my asynchronous task would actually work or
that I&amp;#8217;d used the correct configuration for my&amp;nbsp;needs!&lt;/p&gt;
&lt;p&gt;Celery also has &lt;a class="reference external" href="http://celery.readthedocs.org/en/latest/faq.html#does-celery-have-many-dependencies"&gt;many dependencies&lt;/a&gt; in order to be able to talk with the different broker backends it supports,
improve multithreading support etc. They may be required in enterprise apps but not for most Django web based&amp;nbsp;projects.&lt;/p&gt;
&lt;p&gt;So, for small-to-average projects I recommend using a different asynchronous task solution instead of celery, particularly
(as you&amp;#8217;ve already guessed from the title of this post) &lt;a class="reference external" href="http://python-rq.org/"&gt;&lt;span class="caps"&gt;RQ&lt;/span&gt;&lt;/a&gt;. &lt;span class="caps"&gt;RQ&lt;/span&gt; is simpler than celery, it integrates great with django
using the excellent &lt;a class="reference external" href="https://github.com/ui/django-rq"&gt;django-rq&lt;/a&gt; package and doesn&amp;#8217;t actually have any more dependencies beyond redis support which is
used as a broker (however most modern django projects already use redis for their caching needs as an  alternative
to&amp;nbsp;memcached).&lt;/p&gt;
&lt;p&gt;It even supports supports job scheduling through the &lt;a class="reference external" href="https://github.com/ui/rq-scheduler"&gt;rq-scheduler&lt;/a&gt; package (celery also supports
job scheduling through celery beat): Run a different process (scheduler) that polls the job
scheduling queue for any jobs that need to be run because of scheduling and if yes put them to
the normal job&amp;nbsp;queue.&lt;/p&gt;
&lt;p&gt;Although &lt;span class="caps"&gt;RQ&lt;/span&gt; and frieds are really easy to use (and have nice documentation) I wasn&amp;#8217;t able to find
a &lt;em&gt;complete&lt;/em&gt; example of using it with django, so I&amp;#8217;ve implemented one
(found at &lt;a class="reference external" href="https://github.com/spapas/django-test-rq"&gt;https://github.com/spapas/django-test-rq&lt;/a&gt; &amp;#8212; since I&amp;#8217;ve updated this project a bit
with new stuff,
please checkout tag django-test-rq-simple &lt;tt class="docutils literal"&gt;git checkout &lt;span class="pre"&gt;django-test-rq-simple&lt;/span&gt;&lt;/tt&gt;) mainly for my own testing
purposes. To help others that want to also use &lt;span class="caps"&gt;RQ&lt;/span&gt; in their project but don&amp;#8217;t know from where
to start, I&amp;#8217;ll present it in the following paragraphs, along with some comments on
how to actually use &lt;span class="caps"&gt;RQ&lt;/span&gt; in your production&amp;nbsp;environment.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-test-rq"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;django-test-rq&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is a simple django project that can be used to asynchronously
run and schedule jobs and examine their behavior. The job to be scheduled just downloads a provided
&lt;span class="caps"&gt;URL&lt;/span&gt; and counts its length. There is only one django application (tasks) that contains two views, one
to display existing tasks and create new ones and one to display some info for the&amp;nbsp;jobs.&lt;/p&gt;
&lt;div class="section" id="models-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id4"&gt;models.py&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Two models (&lt;tt class="docutils literal"&gt;Task&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;ScheduledTask&lt;/tt&gt;) for saving individual tasks and
scheduled tasks and one model (&lt;tt class="docutils literal"&gt;ScheduledTaskInstance&lt;/tt&gt;) to save scheduled
instances of each scheduled&amp;nbsp;task.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rq&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_current_job&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# A model to save information about an asynchronous task&lt;/span&gt;
    &lt;span class="n"&gt;created_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;job_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScheduledTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# A model to save information about a scheduled task&lt;/span&gt;
    &lt;span class="n"&gt;created_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;# A scheduled task has a common job id for all its occurences&lt;/span&gt;
    &lt;span class="n"&gt;job_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScheduledTaskInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# A model to save information about instances of a scheduled task&lt;/span&gt;
    &lt;span class="n"&gt;scheduled_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ScheduledTask&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="forms-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5"&gt;forms.py&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A very simple form to create a new&amp;nbsp;task.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; A simple form to read a url from the user in order to find out its length&lt;/span&gt;
&lt;span class="sd"&gt;    and either run it asynchronously or schedule it schedule_times times,&lt;/span&gt;
&lt;span class="sd"&gt;    every schedule_interval seconds.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;URL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Enter a url (starting with http/https) to start a job that will download it and count its words&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;How many times to run this job. Leave empty or 0 to run it only once.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;schedule_interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;How much time (in seconds) between runs of the job. Leave empty to run it only once.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TaskForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_times&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;schedule_interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_interval&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;schedule_interval&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;schedule_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Please fill both schedule_times and schedule_interval to schedule a job or leave them both empty&amp;#39;&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_times&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_interval&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="views-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;views.py&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is actually very simple if you&amp;#8217;re familiar with Class Based Views. Two CBVs
are defined, one for the Task form + Task display and another for the Job&amp;nbsp;display.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic.edit&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormView&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TemplateView&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TaskForm&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_url_words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scheduled_get_url_words&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ScheduledTask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rq.job&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;django_rq&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TasksHomeFormView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FormView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    A class that displays a form to read a url to read its contents and if the job&lt;/span&gt;
&lt;span class="sd"&gt;    is to be scheduled or not and information about all the tasks and scheduled tasks.&lt;/span&gt;

&lt;span class="sd"&gt;    When the form is submitted, the task will be either scheduled based on the&lt;/span&gt;
&lt;span class="sd"&gt;    parameters of the form or will be just executed asynchronously immediately.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TaskForm&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;tasks_home.html&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;success_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_times&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;schedule_interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;schedule_interval&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;schedule_times&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;schedule_interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;# Schedule the job with the form parameters&lt;/span&gt;
            &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;django_rq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_scheduler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;scheduled_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;scheduled_get_url_words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;schedule_interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;repeat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;schedule_times&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;# Just execute the job asynchronously&lt;/span&gt;
            &lt;span class="n"&gt;get_url_words&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TasksHomeFormView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TasksHomeFormView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;tasks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;-created_on&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;scheduled_tasks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScheduledTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;-created_on&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JobTemplateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TemplateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    A simple template view that gets a job id as a kwarg parameter&lt;/span&gt;
&lt;span class="sd"&gt;    and tries to fetch that job from RQ. It will then print all attributes&lt;/span&gt;
&lt;span class="sd"&gt;    of that object using __dict__.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;job.html&amp;#39;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JobTemplateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;redis_conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;django_rq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;job&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;redis_conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__dict__&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;job&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="tasks-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;tasks.py&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Here two jobs are defined: One to be used for simple asynchronous tasks and the
other to be used for scheduled asynchronous tasks (since for asynchronous tasks
we wanted to group their runs per job&amp;nbsp;id).&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&amp;#64;job&lt;/tt&gt; decorator will add the &lt;tt class="docutils literal"&gt;delay()&lt;/tt&gt; method (used in &lt;tt class="docutils literal"&gt;views.py&lt;/tt&gt;) to
the function. It&amp;#8217;s not really required for &lt;tt class="docutils literal"&gt;scheduled_get_url_words&lt;/tt&gt; since
it&amp;#8217;s called through the &lt;tt class="docutils literal"&gt;scheduled.schedule&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;When a task is finished, it can return a value (like we do in &lt;tt class="docutils literal"&gt;return task.result&lt;/tt&gt;)
which will be saved for a limited amount of time (500 seconds by default - could be
even saved for ever) to redis.
This may be useful in some cases, however, I think that for normal web applications it&amp;#8217;s
not that useful, and since here we use normal django models
for each task, we can save it to that model&amp;#8217;s instance&amp;nbsp;instead.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScheduledTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScheduledTaskInstance&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rq&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_current_job&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django_rq&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;


&lt;span class="nd"&gt;@job&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_url_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# This creates a Task instance to save the job instance and job result&lt;/span&gt;
    &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_current_job&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;


&lt;span class="nd"&gt;@job&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scheduled_get_url_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    This creates a ScheduledTask instance for each group of&lt;/span&gt;
&lt;span class="sd"&gt;    scheduled task - each time this scheduled task is run&lt;/span&gt;
&lt;span class="sd"&gt;    a new instance of ScheduledTaskInstance will be created&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_current_job&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScheduledTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_or_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ScheduledTaskInstance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;scheduled_task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response_len&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="settings-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;settings.py&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;123&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.messages&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.staticfiles&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;django_extensions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django_rq&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;tasks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;MIDDLEWARE_CLASSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.sessions.middleware.SessionMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.common.CommonMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.csrf.CsrfViewMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.auth.middleware.AuthenticationMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.auth.middleware.SessionAuthenticationMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.messages.middleware.MessageMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.clickjacking.XFrameOptionsMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ROOT_URLCONF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django_test_rq.urls&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;WSGI_APPLICATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django_test_rq.wsgi.application&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;ENGINE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.db.backends.sqlite3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;NAME&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;db.sqlite3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LANGUAGE_CODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;en-us&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;TIME_ZONE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;UTC&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;USE_I18N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;USE_L10N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;USE_TZ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/static/&amp;#39;&lt;/span&gt;

&lt;span class="c"&gt;# Use redis for caches&lt;/span&gt;
&lt;span class="n"&gt;CACHES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;BACKEND&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;django_redis.cache.RedisCache&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;LOCATION&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;redis://127.0.0.1:6379/0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;OPTIONS&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;quot;CLIENT_CLASS&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;django_redis.client.DefaultClient&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Use the same redis as with caches for RQ&lt;/span&gt;
&lt;span class="n"&gt;RQ_QUEUES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;USE_REDIS_CACHE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;SESSION_ENGINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;django.contrib.sessions.backends.cache&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;SESSION_CACHE_ALIAS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;RQ_SHOW_ADMIN_LINK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c"&gt;# Add a logger for rq_scheduler in order to display when jobs are queueud&lt;/span&gt;
&lt;span class="n"&gt;LOGGING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;disable_existing_loggers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;formatters&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;simple&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;format&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;handlers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;console&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;level&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;DEBUG&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;logging.StreamHandler&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;formatter&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;simple&amp;#39;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;loggers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;django.request&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;handlers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;console&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;level&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;DEBUG&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;propagate&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;rq_scheduler&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;handlers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;console&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;level&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;DEBUG&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;propagate&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, rq_scheduler won&amp;#8217;t log anything so we won&amp;#8217;t be able to see
any output when new instances of each scheduled task are queued for execution.
That&amp;#8217;s why we&amp;#8217;ve overriden the &lt;span class="caps"&gt;LOGGING&lt;/span&gt; setting in order to actually log
rq_scheduler output to the&amp;nbsp;console.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="running-the-project"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9"&gt;Running the&amp;nbsp;project&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I recommend using &lt;a class="reference external" href="https://www.vagrantup.com/"&gt;Vagrant&lt;/a&gt; to start a stock ubuntu/trusty32 box. After that, install redis, virtualenv and virtualenvwrapper
and create/activate a virtualenv named &lt;tt class="docutils literal"&gt;rq&lt;/tt&gt;. You can go to the home directory of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-test-rq&lt;/span&gt;&lt;/tt&gt;
and install requirements through &lt;tt class="docutils literal"&gt;pip install requirements.txt&lt;/tt&gt; and create the database tables with
&lt;tt class="docutils literal"&gt;python manage.py migrate&lt;/tt&gt;. Finally you may run the project with &lt;tt class="docutils literal"&gt;python manage.py runserver_plus&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="rqworker-and-rqscheduler"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id10"&gt;rqworker and&amp;nbsp;rqscheduler&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before scheduling any tasks we need to run two more&amp;nbsp;processes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;rqworker: This is a worker that dequeues jobs from the queue and executes them. We could run more than one onstance of this job if we need&amp;nbsp;it.&lt;/li&gt;
&lt;li&gt;rqscheduler: This is a process that runs every one minute and checks if there are scheduled jobs that have to be executed. If yes, it will add them to the queue in order to be executed by a&amp;nbsp;worker.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="for-development"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11"&gt;For&amp;nbsp;development&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you want to run rqworker and rqscheduler for your development environment you can just do it with
running &lt;tt class="docutils literal"&gt;python manage.py rqworker&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;python mange.py rqscheduler&lt;/tt&gt; through screen/tmux. If everything
is allright you should see tasks being added to the queue and scheduled (you may need to refresh the
homepage before seeing everything since a task may be executed after the response is&amp;nbsp;created).&lt;/p&gt;
&lt;p&gt;Also, keep in mind that rqscheduler runs once every minute by default so you may need to wait up to
minute to see a &lt;tt class="docutils literal"&gt;ScheduledTask&lt;/tt&gt; instance. Also, this means that you can&amp;#8217;t run more than one scheduled
task instance per&amp;nbsp;minute.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="for-production"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12"&gt;For&amp;nbsp;production&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Trying to create daemons through screen is not
sufficient for a production envornment since we&amp;#8217;d like to actually have logging, monitoring and of course
automatically start rqworker and rqscheduler when the server&amp;nbsp;boots.&lt;/p&gt;
&lt;p&gt;For this, I recommend using the &lt;a class="reference external" href="http://supervisord.org/"&gt;supervisord&lt;/a&gt; tool which
can be used to monitor and control a number of processes. There are other similar tools, however I&amp;#8217;ve
found supervisord the easier to&amp;nbsp;use.&lt;/p&gt;
&lt;p&gt;In order to monitor/control a process through supervisord you need to add a &lt;tt class="docutils literal"&gt;[program:progrname]&lt;/tt&gt; section in
supervisord&amp;#8217;s configuration and pass a number of parameters. The &lt;tt class="docutils literal"&gt;progname&lt;/tt&gt; is the name of the monitoring
process. Here&amp;#8217;s how rqworker can be configured using&amp;nbsp;supervisord:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
[program:rqworker]
command=python manage.py rqworker
directory=/vagrant/progr/py/rq/django-test-rq
environment=PATH=&amp;quot;/home/vagrant/.virtualenvs/rq/bin&amp;quot;
user=vagrant
&lt;/pre&gt;
&lt;p&gt;The options used will chdir to &lt;tt class="docutils literal"&gt;directory&lt;/tt&gt; and execute &lt;tt class="docutils literal"&gt;command&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;user&lt;/tt&gt;. The &lt;tt class="docutils literal"&gt;environment&lt;/tt&gt;
option can be used to set envirotnment variables - here we set &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/tt&gt; in order to use a specific
virtual environment. This will allow you to monitor rqworker through supervisord and log its
output to a file in &lt;tt class="docutils literal"&gt;/var/log/supervisor&lt;/tt&gt; (by default). A similar entry needs to be added for
rqscheduler of course. If everything has been configured correctly, when you reload the supervisord
settings you can run &lt;tt class="docutils literal"&gt;sudo /usr/bin/supervisorctl&lt;/tt&gt; and should see something&amp;nbsp;like&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
rqscheduler                      RUNNING    pid 1561, uptime 0:00:03
rqworker                         RUNNING    pid 1562, uptime 0:00:03
&lt;/pre&gt;
&lt;p&gt;Also, tho log files should contain some debug&amp;nbsp;info.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id13"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Although using job queues makes it more difficult for the developer and adds at least one
(and probably more) points of failure to a project (the workers, the broker etc) their
usage, even for very simple projects is&amp;nbsp;unavoidable.&lt;/p&gt;
&lt;p&gt;Unless a complex, enterprise solution like celery is really required for a project
I recommend using the much simpler and easier to configure &lt;span class="caps"&gt;RQ&lt;/span&gt; for all your
asynchronous and scheduled task needs. Using &lt;span class="caps"&gt;RQ&lt;/span&gt; (and the relative projects django-rq
and rq-scheduler) we can easily add production ready queueued and scheduled jobs to
any django&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;In this article we presented a small introduction to &lt;span class="caps"&gt;RQ&lt;/span&gt; and its friends and saw how
to configure django to use it in a production ready environment using a small
django project (&lt;a class="reference external" href="https://github.com/spapas/django-test-rq"&gt;https://github.com/spapas/django-test-rq&lt;/a&gt;) which was implemented as a companion
to help readers quickly test the concepts presented&amp;nbsp;here.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 27 Jan 2015 14:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-01-27:2015/01/27/async-tasks-with-django-rq/</guid><category>django</category><category>python</category><category>tasks</category><category>jobs</category><category>rq</category><category>django-rq</category><category>asynchronous</category><category>scheduling</category><category>redis</category></item><item><title>Django model auditing</title><link>http://spapas.github.io/2015/01/21/django-model-auditing/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id5"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-simple-auditing-functionality-ourselves" id="id6"&gt;Adding simple auditing functionality&amp;nbsp;ourselves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#example" id="id7"&gt;Example&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#models-py" id="id8"&gt;models.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#forms-py" id="id9"&gt;forms.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#views-py" id="id10"&gt;views.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#urls-py" id="id11"&gt;urls.py&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#templates" id="id12"&gt;templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-django-simple-history" id="id13"&gt;Using django-simple-history&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#installation" id="id14"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#id1" id="id15"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#usage" id="id16"&gt;Usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-django-reversion" id="id17"&gt;Using django-reversion&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#id2" id="id18"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#id3" id="id19"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#id4" id="id20"&gt;Usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#comparing-versions-with-django-reversion-compare" id="id21"&gt;Comparing versions with&amp;nbsp;django-reversion-compare&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id22"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An auditing trail is a common requirement in most non-trivial applications. Organizations
need to know &lt;em&gt;who&lt;/em&gt; did the change, &lt;em&gt;when&lt;/em&gt; it was done and &lt;em&gt;what&lt;/em&gt; was actually changed.
In this post we will see three
different solution in order to add this functionality in Django: doing it ourselves,
using django-simple-history and using&amp;nbsp;django-reversion.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update 24/09/2015:&lt;/em&gt; Added a paragraph describing the django-reversion-compare which is
a great addon for django-reversion that makes finding differences between versions a&amp;nbsp;breeze!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-simple-auditing-functionality-ourselves"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Adding simple auditing functionality&amp;nbsp;ourselves&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A simple way to actually do auditing is to keep four extra fields in our models:
&lt;tt class="docutils literal"&gt;created_by&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;created_on&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;modified_by&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;modified_on&lt;/tt&gt;. The first two
will be filled when the model instance is created while the latter two will be
changed whenever the model instance is saved. So we only have &lt;em&gt;who&lt;/em&gt; and &lt;em&gt;whe&lt;/em&gt;.
Sometimes, these are enough so let&amp;#8217;s see how easy it is to implement it in&amp;nbsp;django.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll need an abstract model that could be used as a base class for models that need&amp;nbsp;auditing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Auditable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;created_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AUTH_USER_MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;created_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;modified_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;modified_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AUTH_USER_MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;modified_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Models inheriting from &lt;tt class="docutils literal"&gt;Auditable&lt;/tt&gt; will contain their datetime of creation and modification
which will be automatically filled using the very usefull &lt;tt class="docutils literal"&gt;auto_now_add_&lt;/tt&gt; (which will
set the current datetime when the model instance is created) and &lt;tt class="docutils literal"&gt;auto_now_&lt;/tt&gt; (which will
set the current datetime when the model instance is&amp;nbsp;modified).&lt;/p&gt;
&lt;p&gt;Such models will also have two foreign keys to &lt;tt class="docutils literal"&gt;User&lt;/tt&gt;, one for the user
that created the and one of the user that modified them. The problem with these two fields
is that they cannot be filled automatically (like the datetimes) because the user that
actually did create/change the objects must be&amp;nbsp;provided!&lt;/p&gt;
&lt;p&gt;Since I am really fond of CBVs I will present a simple mixin that can be used with CreateView
and UpdateView and does exactly&amp;nbsp;that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuditableMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modified_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuditableMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above mixin overrides the &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;CreateView&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;UpdateView&lt;/tt&gt;:
First it checks if the object is created (if it is created it won&amp;#8217;t be saved in the
database yet thus it won&amp;#8217;t have an id) in order to set the &lt;tt class="docutils literal"&gt;created_by&lt;/tt&gt; attribute to
the current user. After that it will set the &lt;tt class="docutils literal"&gt;modified_by&lt;/tt&gt; attribute of the object to
the current user. Finally, it will call the next &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method to do whatever
is required (save the model instance and redirect to &lt;tt class="docutils literal"&gt;success_url&lt;/tt&gt; by&amp;nbsp;default).&lt;/p&gt;
&lt;p&gt;The views using &lt;tt class="docutils literal"&gt;AuditableMixin&lt;/tt&gt; should allow only logged in users (or else an
exception will be thrown). Also, don&amp;#8217;t forget to exclude the &lt;tt class="docutils literal"&gt;created_by&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;modified_by&lt;/tt&gt;
fields from your model form (&lt;tt class="docutils literal"&gt;created_on&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;modified_on&lt;/tt&gt; will automatically be&amp;nbsp;excluded).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="example"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7"&gt;Example&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s see a simple example of creating a small django application using the previously defined abstract model and&amp;nbsp;mixin:&lt;/p&gt;
&lt;div class="section" id="models-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;models.py&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.urlresolvers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;auditable.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Auditable&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Auditable&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_absolute_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;book_list&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above we suppose that the &lt;tt class="docutils literal"&gt;Auditable&lt;/tt&gt; abstract model is imported from the
&lt;tt class="docutils literal"&gt;auditable.models&lt;/tt&gt; module and that a view named &lt;tt class="docutils literal"&gt;book_list&lt;/tt&gt; that shows all books&amp;nbsp;exists.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="forms-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9"&gt;forms.py&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModelForm&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;author&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Show only &lt;tt class="docutils literal"&gt;name&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;author&lt;/tt&gt; fields (and not the auditable fields) in the &lt;tt class="docutils literal"&gt;Book ModelForm&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="views-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10"&gt;views.py&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic.edit&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;auditable.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AuditableMixin&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BookForm&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuditableMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BookForm&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookUpdateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuditableMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BookForm&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We import the &lt;tt class="docutils literal"&gt;AuditableMixin&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;auditable.views&lt;/tt&gt; and make our Create and Update views
inherit from this mixin also in addition to &lt;tt class="docutils literal"&gt;CreateView&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;UpdateView&lt;/tt&gt;. Pay attention that our
mixin is placed &lt;em&gt;before&lt;/em&gt; CreateView in order to call &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; in the proper order: When multiple
inheritance is used like this python will check each class from left to right to find the proper method
and call it. For example, in our &lt;tt class="docutils literal"&gt;BookCreateView&lt;/tt&gt;, when the &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method is called, python
will first check if &lt;tt class="docutils literal"&gt;BookCreateView&lt;/tt&gt; has a &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method. Since it does not, it will check
if &lt;tt class="docutils literal"&gt;AuditableMixin&lt;/tt&gt; has a &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method and call it. Now, we are calling the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;super(...).form_valid()&lt;/span&gt;&lt;/tt&gt; in the
&lt;tt class="docutils literal"&gt;AuditableMixin&lt;/tt&gt; &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt;, so the &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; of &lt;tt class="docutils literal"&gt;CreateView&lt;/tt&gt; will &lt;em&gt;also&lt;/em&gt; be&amp;nbsp;called.&lt;/p&gt;
&lt;p&gt;A simple &lt;tt class="docutils literal"&gt;ListView&lt;/tt&gt; is also added to just show the info on all&amp;nbsp;books.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="urls-py"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11"&gt;urls.py&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BookCreateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BookUpdateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BookListView&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^accounts/login/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.contrib.auth.views.login&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^accounts/logout/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.contrib.auth.views.logout&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^create/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BookCreateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;create_book&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^update/(?P&amp;lt;pk&amp;gt;\d+)/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BookUpdateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;update_book&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BookListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;book_list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just add the previously defined Create/Update/List views along with a login/logout&amp;nbsp;views.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="templates"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12"&gt;templates&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You&amp;#8217;ll need four&amp;nbsp;templates:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;books/book_list.html: Show the list of&amp;nbsp;books&lt;/li&gt;
&lt;li&gt;books/book_form.html: Show the book editing&amp;nbsp;form&lt;/li&gt;
&lt;li&gt;registration/login.html: Login&amp;nbsp;form&lt;/li&gt;
&lt;li&gt;registration/logout.html: Logout&amp;nbsp;message&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="using-django-simple-history"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id13"&gt;Using&amp;nbsp;django-simple-history&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/treyhunner/django-simple-history"&gt;django-simple-history&lt;/a&gt;  can be used to not only store the user and date of each modification
but a different version for each modification. To do that, for every model that is registered
to be used with django-simple-history, it wil create a second table in
the database hosting all versions (historical records) of that model. As we can understand this is really powerfull
since we can see exactly what was changed and also do normal &lt;span class="caps"&gt;SQL&lt;/span&gt; queries on&amp;nbsp;that!&lt;/p&gt;
&lt;div class="section" id="installation"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id14"&gt;Installation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use django-simple-history in a project, after we do a &lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;django-simple-history&lt;/span&gt;&lt;/tt&gt;,
we just need to add it to &lt;tt class="docutils literal"&gt;INSTALLED_APPS&lt;/tt&gt; and
add the &lt;tt class="docutils literal"&gt;simple_history.middleware.HistoryRequestMiddleware&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;MIDDLEWARE_CLASSES&lt;/tt&gt; list.&lt;/p&gt;
&lt;p&gt;Finally, to keep the historical records for a model, just add an instace of &lt;tt class="docutils literal"&gt;HistoricalRecords&lt;/tt&gt; to this&amp;nbsp;model.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15"&gt;Example&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For example, our previously defined &lt;tt class="docutils literal"&gt;Book&lt;/tt&gt; model will be modified like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;class SHBook(models.Model):
    name = models.CharField(max_length=128)
    author = models.CharField(max_length=128)

    def get_absolute_url(self):
        return reverse(&amp;quot;shbook_list&amp;quot;)

    history = HistoricalRecords()
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we run &lt;tt class="docutils literal"&gt;python manage.py makemigrations&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;migrate&lt;/tt&gt; this, we&amp;#8217;ll see that beyond the table for SHBook, a table for HistoricalSHBook will be&amp;nbsp;created:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
Migrations for 'sample':
  0002_historicalshbook_shbook.py:
    - Create model HistoricalSHBook
    - Create model SHBook
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s see the schema of&amp;nbsp;historicalshbook:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
CREATE TABLE &amp;quot;sample_historicalshbook&amp;quot; (
    &amp;quot;id&amp;quot; integer NOT NULL,
    &amp;quot;name&amp;quot; varchar(128) NOT NULL,
    &amp;quot;author&amp;quot; varchar(128) NOT NULL,
    &amp;quot;history_id&amp;quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    &amp;quot;history_date&amp;quot; datetime NOT NULL,
    &amp;quot;history_type&amp;quot; varchar(1) NOT NULL,
    &amp;quot;history_user_id&amp;quot; integer NULL REFERENCES &amp;quot;auth_user&amp;quot; (&amp;quot;id&amp;quot;)
);
&lt;/pre&gt;
&lt;p&gt;So we see that it has the &lt;em&gt;same&lt;/em&gt; fields as with &lt;tt class="docutils literal"&gt;SHBook&lt;/tt&gt; (&lt;tt class="docutils literal"&gt;id, name, author&lt;/tt&gt;) with the addition of
the primary key (&lt;tt class="docutils literal"&gt;history_id&lt;/tt&gt;) of this historical record, the date and user that did the change
(&lt;tt class="docutils literal"&gt;history_date&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;history_user_id&lt;/tt&gt;) and the type of the record (created / update /&amp;nbsp;delete).&lt;/p&gt;
&lt;p&gt;So, just by adding a &lt;tt class="docutils literal"&gt;HistoricalRecords()&lt;/tt&gt; attribute to our model definition we&amp;#8217;ll get complete auditing
for the instance of that&amp;nbsp;model&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="usage"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16"&gt;Usage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To find out information about the historical records we&amp;#8217;ll just use the &lt;tt class="docutils literal"&gt;HistoricalRecords()&lt;/tt&gt; attribute
of that&amp;nbsp;model:&lt;/p&gt;
&lt;p&gt;For example, running &lt;tt class="docutils literal"&gt;SHBook.history.filter(id=1)&lt;/tt&gt; will return all historical records of the book with
&lt;tt class="docutils literal"&gt;id = 1&lt;/tt&gt;. For each one of them we have can use the&amp;nbsp;following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;get the user that made the change through the &lt;tt class="docutils literal"&gt;history_user&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;get the date of the change through the &lt;tt class="docutils literal"&gt;history_date&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;get the type of the change through the &lt;tt class="docutils literal"&gt;history_type&lt;/tt&gt; attribute (and the corresponding &lt;tt class="docutils literal"&gt;get_history_type_dispaly&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;get a model instance as it was then through the &lt;tt class="docutils literal"&gt;history_object&lt;/tt&gt; attribute (in order to &lt;tt class="docutils literal"&gt;save()&lt;/tt&gt; it and revert to this&amp;nbsp;version)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="using-django-reversion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id17"&gt;Using&amp;nbsp;django-reversion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/etianen/django-reversion"&gt;django-reversion&lt;/a&gt;  offers more or less the same functionality of django-simple-history by following a different philosophy:
Instead of creating an extra table holding the history records for each model, it insteads converts all the fields of each model
to json and stores that &lt;span class="caps"&gt;JSON&lt;/span&gt; in the database in a text&amp;nbsp;field.&lt;/p&gt;
&lt;p&gt;This has the advantage that no extra tables are created to the database but the disadvantage that you can&amp;#8217;t easily query
your historical records. So you may choose one or the other depending on your actual&amp;nbsp;requirements.&lt;/p&gt;
&lt;div class="section" id="id2"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18"&gt;Installation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use django-reversion in a project, after we do a &lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;django-reversion&lt;/span&gt;&lt;/tt&gt;,
we just need to add it to &lt;tt class="docutils literal"&gt;INSTALLED_APPS&lt;/tt&gt; and
add the &lt;tt class="docutils literal"&gt;reversion.middleware.RevisionMiddleware&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;MIDDLEWARE_CLASSES&lt;/tt&gt; list.&lt;/p&gt;
&lt;p&gt;In order to save the revisions of a model, you need to register this model to django-reversion. This can be
done either through the django-admin, by inheriting the admin class of that model from &lt;tt class="docutils literal"&gt;reversion.VersionAdmin&lt;/tt&gt;
or, if you don&amp;#8217;t want to use the admin by &lt;tt class="docutils literal"&gt;reversion.register&lt;/tt&gt; decorator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id3"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id19"&gt;Example&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use django-reversion to keep track of changes to &lt;tt class="docutils literal"&gt;Book&lt;/tt&gt; we can modify it like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;@reversion.register
class RBook(models.Model):
    name = models.CharField(max_length=128)
    author = models.CharField(max_length=128)

    def get_absolute_url(self):
        return reverse(&amp;quot;rbook_list&amp;quot;)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;django-reversion uses two tables in the database to keep track of revisions: &lt;tt class="docutils literal"&gt;revision&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;version&lt;/tt&gt;. Let&amp;#8217;s
take a look at their&amp;nbsp;schemata:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
.schema reversion_revision
CREATE TABLE &amp;quot;reversion_revision&amp;quot; (
    &amp;quot;id&amp;quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    &amp;quot;manager_slug&amp;quot; varchar(200) NOT NULL,
    &amp;quot;date_created&amp;quot; datetime NOT NULL,
    &amp;quot;comment&amp;quot; text NOT NULL,
    &amp;quot;user_id&amp;quot; integer NULL REFERENCES &amp;quot;auth_user&amp;quot; (&amp;quot;id&amp;quot;)
);

.schema reversion_version
CREATE TABLE &amp;quot;reversion_version&amp;quot; (
    &amp;quot;id&amp;quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    &amp;quot;object_id&amp;quot; text NOT NULL,
    &amp;quot;object_id_int&amp;quot; integer NULL,
    &amp;quot;format&amp;quot; varchar(255) NOT NULL,
    &amp;quot;serialized_data&amp;quot; text NOT NULL,
    &amp;quot;object_repr&amp;quot; text NOT NULL,
    &amp;quot;content_type_id&amp;quot; integer NOT NULL REFERENCES &amp;quot;django_content_type&amp;quot; (&amp;quot;id&amp;quot;),
    &amp;quot;revision_id&amp;quot; integer NOT NULL REFERENCES &amp;quot;reversion_revision&amp;quot; (&amp;quot;id&amp;quot;)
);
&lt;/pre&gt;
&lt;p&gt;As we can understand, the &lt;tt class="docutils literal"&gt;revision&lt;/tt&gt; table holds information like who created this
revison (&lt;tt class="docutils literal"&gt;user_id&lt;/tt&gt;) and when (&lt;tt class="docutils literal"&gt;date_created&lt;/tt&gt;) while the &lt;tt class="docutils literal"&gt;version&lt;/tt&gt; stores
a reference to the object that was modified (through a GenericForeignKey) and
the actual data (in the &lt;tt class="docutils literal"&gt;serialized_data&lt;/tt&gt; field). By default it uses &lt;span class="caps"&gt;JSON&lt;/span&gt;
to serialize the data (the serialization format is in the &lt;tt class="docutils literal"&gt;format&lt;/tt&gt; field). There&amp;#8217;s
an one-to-one relation between &lt;tt class="docutils literal"&gt;revision&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;version&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;If we create an instance of &lt;tt class="docutils literal"&gt;RBook&lt;/tt&gt; we&amp;#8217;ll see the following in the&amp;nbsp;database:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
sqlite&amp;gt; select * from reversion_revision;
1|default|2015-01-21 10:31:25.233000||1

sqlite&amp;gt; select * from reversion_version;
1|1|1|json|[{&amp;quot;fields&amp;quot;: {&amp;quot;name&amp;quot;: &amp;quot;asdasdasd&amp;quot;, &amp;quot;author&amp;quot;: &amp;quot;asdasd&amp;quot;}, &amp;quot;model&amp;quot;: &amp;quot;sample.rbook&amp;quot;, &amp;quot;pk&amp;quot;: 1}]|RBook object|12|1
&lt;/pre&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;date_created&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;user_id&lt;/tt&gt; are stored on &lt;tt class="docutils literal"&gt;revision&lt;/tt&gt; while &lt;tt class="docutils literal"&gt;format&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;serialized_data&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;content_type_id&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;object_id_int&lt;/tt&gt; (the &lt;tt class="docutils literal"&gt;GenericForeignKey&lt;/tt&gt;) are stored in &lt;tt class="docutils literal"&gt;version&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id4"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id20"&gt;Usage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To find out information about an object you have to use the &lt;tt class="docutils literal"&gt;reversion.get_for_object(object)&lt;/tt&gt; method. In order to be
easily used in templates I recommend creating the following &lt;tt class="docutils literal"&gt;get_versions()&lt;/tt&gt; method in each model that is registered with&amp;nbsp;django-reversion&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
def get_versions(self):
    return reversion.get_for_object(self)
&lt;/pre&gt;
&lt;p&gt;Now, each version has a &lt;tt class="docutils literal"&gt;revision&lt;/tt&gt; attribute for the corresponding revision and can be used to do the&amp;nbsp;following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;get the user that made the change through the &lt;tt class="docutils literal"&gt;revision.user&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;get the date of the change through the &lt;tt class="docutils literal"&gt;revision.date_created&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;get the values of the object fields as they were in this revision using the &lt;tt class="docutils literal"&gt;field_dict&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;get a model instance as it was on that revision using the &lt;tt class="docutils literal"&gt;object_version.object&lt;/tt&gt; attribute&lt;/li&gt;
&lt;li&gt;revert to that previous version of that object using the &lt;tt class="docutils literal"&gt;revert()&lt;/tt&gt; method&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="comparing-versions-with-django-reversion-compare"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id21"&gt;Comparing versions with&amp;nbsp;django-reversion-compare&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A great addon for django-version is &lt;a class="reference external" href="github.com/jedie/django-reversion-compare"&gt;django-reversion-compare&lt;/a&gt; which helps you find out differences
between versions of your objects. When you use django-reversion-compare, you&amp;#8217;ll be able to select
two (different) versions of your object and you&amp;#8217;ll be presented with a list of all the differences
found in the fields of that object between the two versions. The diff algorithm is smart, so you&amp;#8217;ll
be able to easily recognise the&amp;nbsp;changes.&lt;/p&gt;
&lt;p&gt;To use django-reversion-compare, after installing it you should just inherit your admin views from
&lt;tt class="docutils literal"&gt;reversion_compare.admin.CompareVersionAdmin&lt;/tt&gt; (instead of &lt;tt class="docutils literal"&gt;reversion.VersionAdmin&lt;/tt&gt;) and you&amp;#8217;ll
get the reversion-compare views instead of reversion views in the admin for the history of the&amp;nbsp;object.&lt;/p&gt;
&lt;p&gt;Also, in case you need to give access to normal, non-admin users to the history of an object (this is
useful for auditing reasons), you can use the &lt;tt class="docutils literal"&gt;reversion_compare.views.HistoryCompareDetailView&lt;/tt&gt;
as a normal &lt;tt class="docutils literal"&gt;DetailView&lt;/tt&gt; to create a non-admin history and compare diff&amp;nbsp;view.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id22"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the above we say that it is really easy to add basic (&lt;em&gt;who&lt;/em&gt; and &lt;em&gt;when&lt;/em&gt;) auditing capabilities to your models: You just need to
inherit your models from the &lt;tt class="docutils literal"&gt;Auditable&lt;/tt&gt; abstract class and inherit your Create and Update CBVs from &lt;tt class="docutils literal"&gt;AuditableMixin&lt;/tt&gt;.
If you want to know exactly &lt;em&gt;what&lt;/em&gt; was changed then you have two solutions: django-simple-history to create an extra table for
each of your models so you&amp;#8217;ll be able to query your historical records (and easily extra aggregates, statistics etc) and
django-reversion to save each version as a json object, so no extra tables will be&amp;nbsp;created.&lt;/p&gt;
&lt;p&gt;All three solutions for auditing have been implemented in a sample project at &lt;a class="reference external" href="https://github.com/spapas/auditing-sample"&gt;https://github.com/spapas/auditing-sample&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can clone the project and, preferrably in a virtual environment, install requirements (&lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;-r&lt;/span&gt; requirements.txt&lt;/tt&gt;),
do a migrate (&lt;tt class="docutils literal"&gt;python manage.py migrate&lt;/tt&gt; &amp;#8212; uses sqlite3 by default) and run the local development
server (&lt;tt class="docutils literal"&gt;python manage.py ruinserver&lt;/tt&gt;).&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Wed, 21 Jan 2015 14:20:00 +0200</pubDate><guid>tag:spapas.github.io,2015-01-21:2015/01/21/django-model-auditing/</guid><category>django</category><category>python</category><category>auditing</category></item><item><title>Change the primary color of bootstrap material design</title><link>http://spapas.github.io/2014/12/16/change-bootstrap-material-primary-color/</link><description>&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/FezVrasta/bootstrap-material-design"&gt;Bootstrap Material Design&lt;/a&gt; is a great theme that sits on top of &lt;a class="reference external" href="http://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt; and transforms it to
&lt;a class="reference external" href="http://www.google.com/design/spec/material-design/introduction.html"&gt;Material Design&lt;/a&gt;! The great thing about Bootstrap Material Design is that you just need to include
its css and js files after your Bootstrap files and&amp;nbsp;&amp;#8230;&lt;/p&gt;
&lt;p&gt;boom! Your page is Material Design&amp;nbsp;compatible!&lt;/p&gt;
&lt;object data="https://google.github.io/material-design-icons/action/svg/ic_thumb_up_24px.svg" type="image/svg+xml"&gt;
&lt;/object&gt;
&lt;p&gt;A nice feature of Bootstrap Material Design is that you can change its default color to a new one (I
don&amp;#8217;t really like the current - greenish one). This is easy for people with less skills however I
found it rather challenging when I tried it. That&amp;#8217;s why I will present a step by step tutorial on
changing the default primary color of the Bootstrap Material Design&amp;nbsp;theme:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-1-get-the-code"&gt;
&lt;h2&gt;Step 1: Get the&amp;nbsp;code&lt;/h2&gt;
&lt;p&gt;Use git to make a local clone of the project with &lt;tt class="docutils literal"&gt;git clone &lt;span class="pre"&gt;https://github.com/FezVrasta/bootstrap-material-design.git&lt;/span&gt;&lt;/tt&gt;. This will create a directory
named &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bootstrap-material-design&lt;/span&gt;&lt;/tt&gt;. Or you can download the latest version of the code using (&lt;a class="reference external" href="https://github.com/FezVrasta/bootstrap-material-design/archive/master.zip"&gt;https://github.com/FezVrasta/bootstrap-material-design/archive/master.zip&lt;/a&gt;)
and unzip it to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bootstrap-material-design&lt;/span&gt;&lt;/tt&gt; directory.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-2-install-node-js-and-npm"&gt;
&lt;h2&gt;Step 2: Install node.js and&amp;nbsp;npm&lt;/h2&gt;
&lt;p&gt;You need to have &lt;a class="reference external" href="http://nodejs.org/"&gt;node.js&lt;/a&gt; and npm installed in your system - this is something very easy so I won&amp;#8217;t go into any details about this. After you have installed
both node.js and npm you need to put them in your path so that you&amp;#8217;ll be able to run &lt;tt class="docutils literal"&gt;npm &lt;span class="pre"&gt;-v&lt;/span&gt;&lt;/tt&gt; without errors and receive something like &lt;tt class="docutils literal"&gt;1.4.14&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-3-install-less"&gt;
&lt;h2&gt;Step 3: Install&amp;nbsp;less&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lesscss.org/"&gt;less&lt;/a&gt; is a &lt;span class="caps"&gt;CSS&lt;/span&gt; preprocessor in which Bootstrap Material Design has been written. To install it, just enter the command &lt;tt class="docutils literal"&gt;npm install &lt;span class="pre"&gt;-g&lt;/span&gt; less&lt;/tt&gt;. After that
you should have a command named &lt;tt class="docutils literal"&gt;lessc&lt;/tt&gt; which, when run would output something like: &lt;tt class="docutils literal"&gt;lessc 2.1.1 (Less Compiler) [JavaScript]&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="step-4-create-the-customizations-files"&gt;
&lt;h2&gt;Step 4: Create the customizations&amp;nbsp;files&lt;/h2&gt;
&lt;p&gt;Go to the directory where you cloned (or unzipped) the Bootstrap Material Design code and create a file named &lt;tt class="docutils literal"&gt;custom.less&lt;/tt&gt; (so, that file should be
in the same folder as with &lt;tt class="docutils literal"&gt;bower.json&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;Gruntfile.js&lt;/tt&gt; etc) with the following&amp;nbsp;contents:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;import &amp;quot;less/material.less&amp;quot;;

// Override &amp;#64;primary color with one took from _colors.less
&amp;#64;primary: &amp;#64;indigo;
&lt;/pre&gt;
&lt;p&gt;(I wanted to use the indigo color as my primary one - you may of course use whichever color from the ones defined in &lt;tt class="docutils literal"&gt;less/_variables.less&lt;/tt&gt; you&amp;nbsp;like)&lt;/p&gt;
&lt;p&gt;This file may contain other default values for variables - if I find anything useful I will add it to this post (also please reply with any&amp;nbsp;recommendations).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 13/10/2015&lt;/strong&gt; After a request from commenter Jofferson Ramirez Tiquez, here&amp;#8217;s a custom.less that overrides more colors from &lt;tt class="docutils literal"&gt;_variables.css&lt;/tt&gt;
(beyond the primary color, it changes the success color to teal and info and warning to the corresponding hex color&amp;nbsp;values):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;#64;import &amp;quot;less/material.less&amp;quot;;

&amp;#64;primary: &amp;#64;indigo;
&amp;#64;success: &amp;#64;teal;
&amp;#64;info: #CFD8DC;
&amp;#64;warning:#455A64;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="step-5-create-your-custom-material-css-file"&gt;
&lt;h2&gt;Step 5: Create your custom material css&amp;nbsp;file&lt;/h2&gt;
&lt;p&gt;Finally, run the following command: &lt;tt class="docutils literal"&gt;lessc custom.less&amp;nbsp; &amp;gt; &lt;span class="pre"&gt;material-custom.css&lt;/span&gt;&lt;/tt&gt;. This will create a file named &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;material-custom.css&lt;/span&gt;&lt;/tt&gt; that contains your
custom version of Bootstrap Material Design! If you want your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;material-custom.css&lt;/span&gt;&lt;/tt&gt; to be compressed, add the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-x&lt;/span&gt;&lt;/tt&gt; option like this:  &lt;tt class="docutils literal"&gt;lessc &lt;span class="pre"&gt;-x&lt;/span&gt; custom.less&amp;nbsp; &amp;gt; &lt;span class="pre"&gt;material-custom.css&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;You may now include &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;material-custom.css&lt;/span&gt;&lt;/tt&gt; instead of &lt;tt class="docutils literal"&gt;material.css&lt;/tt&gt; (or the minified version of it) to your projects and you&amp;#8217;ll have your own primary&amp;nbsp;color!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 16 Dec 2014 16:20:00 +0200</pubDate><guid>tag:spapas.github.io,2014-12-16:2014/12/16/change-bootstrap-material-primary-color/</guid><category>css</category><category>design</category><category>boostrap-material-design</category><category>less</category><category>node.js</category></item><item><title>Retrieving Gmail blocked attachments</title><link>http://spapas.github.io/2014/10/23/retrieve-gmail-blocked-attachments/</link><description>&lt;p&gt;Before services like Dropbox were widely available, some people (including me) were using
their Gmail account as a primitive backup solution: Compress your directory and send it to
your gmail. There. Backup&amp;nbsp;complete.&lt;/p&gt;
&lt;p&gt;However, nothing is so&amp;nbsp;easy&amp;#8230;&lt;/p&gt;
&lt;p&gt;Recently, I wanted to retrieve one of these backups, a .rar containing the complete
source code (since it was written in TeX) of my PhD thesis. The problem was that Gmail blocked the access to these attachments&amp;nbsp;saying&lt;/p&gt;
&lt;blockquote&gt;
Anti-virus warning - 1 attachment contains a virus or blocked file. Downloading this attachment is disabled.&lt;/blockquote&gt;
&lt;p&gt;probably because I had a number of .bat files inside that .rar archive to automate my work&amp;nbsp;:(&lt;/p&gt;
&lt;p&gt;Now what&amp;nbsp;?&lt;/p&gt;
&lt;p&gt;After searching the internet and not founding any solutions, I tried the options that gmail gives for each email. One
particular one cought my interest: &lt;em&gt;Show&amp;nbsp;original&lt;/em&gt;&lt;/p&gt;
&lt;img alt="Here it is!" src="/images/show_original.png" style="width: 780px;" /&gt;
&lt;p&gt;Clicking this option opened a text file with the original, &lt;span class="caps"&gt;MIME&lt;/span&gt; encoded message. The interesting thing of course&amp;nbsp;was&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
------=_NextPart_000_004F_01CA0AED.E63C2A30
Content-Type: application/octet-stream;
      name=&amp;quot;phdstuff.rar&amp;quot;
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
      filename=&amp;quot;phdstuff.rar&amp;quot;

UmFyIRoHAM+QcwAADQAAAAAAAAB0f3TAgCwANAMAAFQEAAACRbXCx8lr9TodMwwAIAAAAG5ld2Zp
bmFsLnR4dA3dEQzM082BF7sB+D3q6QPUNEfwG7vHQgNkiQDTkGvfhOE4mNltIJJlBFMOCQPzPeKD
...
&lt;/pre&gt;
&lt;p&gt;So the whole attachment was contained in that text file, encoded in base64! Now I just
needed to extract it from the email and convert it back to&amp;nbsp;binary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;strong&gt;Important: Before going the python way, please check the 2 June 2015 update at the end of the article for an easier solution!&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;This was very easy to do using Python - some people &lt;a class="reference external" href="http://stackoverflow.com/questions/4067937/getting-mail-attachment-to-python-file-object"&gt;had already asked the same thing on &lt;span class="caps"&gt;SO&lt;/span&gt;&lt;/a&gt;.
So here&amp;#8217;s a simple program that gets an email in text/mime format as input and dumps all&amp;nbsp;attachments:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;email&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Please enter a file to extract attachments from&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message_from_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_payload&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_filename&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="c"&gt;# if it is an attachment&lt;/span&gt;
            &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_filename&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Save this to a file named &lt;tt class="docutils literal"&gt;get_attachments.py&lt;/tt&gt; and, after saving the original message to a file
named &lt;tt class="docutils literal"&gt;0.txt&lt;/tt&gt; run &lt;tt class="docutils literal"&gt;python get_attachments.py 0.txt&lt;/tt&gt; and you&amp;#8217;ll see the attachments of your email in the same&amp;nbsp;folder!&lt;/p&gt;
&lt;blockquote&gt;
Disclaimer: I have to warn you that since Gmail claims that an attachment is &lt;em&gt;not safe&lt;/em&gt; it may be &lt;strong&gt;actually not safe&lt;/strong&gt;. So
you must be 100% sure that you know what you are doing before retrievening your email attachments like this.&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Stefan &lt;a class="reference external" href="https://gist.github.com/stefansundin/a99bbfb6cda873d14fd2"&gt;created an improved version&lt;/a&gt; of the attachment extractor which is also compatible with Python&amp;nbsp;3.4!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update, 12 January 2015&lt;/strong&gt;: Ivana (at the comments section) proposed a different solution that may work
for some files: &lt;em&gt;Use a mobile Gmail client (I tested it with Android) and &amp;quot;Save to Drive&amp;quot; your attachment.
You&amp;#8217;ll then be able to download it from the Google Drive!&lt;/em&gt; I am not sure if this works for all attachments,
however it worked for the source of my PhD thesis! I&amp;#8217;m writing it may not work for all attachments because
when you download something from Google Drive it does a virus check so it may not allow you to download the
attachment and then  you&amp;#8217;ll still need to do it manually using the method below (however &lt;strong&gt;in that case you
must be even more cautious for the case the attachment actualyl contains a malicious file&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update, 2 June 2015&lt;/strong&gt;: Commenter Sumit Chauhan (and Yuri Marx) proposed to change the extension
of the downloaded &lt;span class="caps"&gt;MIME&lt;/span&gt; text file (original message) to eml and open it with Outlook. I don&amp;#8217;t have
Outlook in my system, however I tried opening it with &lt;a class="reference external" href="https://www.mozilla.org/el/thunderbird/"&gt;Thunderbird&lt;/a&gt; and it worked!!! So please
try this solution before trying the pythonic way (especially if you&amp;#8217;re not familiar with&amp;nbsp;python).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Thu, 23 Oct 2014 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2014-10-23:2014/10/23/retrieve-gmail-blocked-attachments/</guid><category>gmail</category><category>python</category><category>security</category><category>google</category></item><item><title>Django non-HTML responses</title><link>http://spapas.github.io/2014/09/15/django-non-html-responses/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#how-are-cbvs-rendered" id="id2"&gt;How are CBVs&amp;nbsp;rendered&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#rendering-to-non-html" id="id3"&gt;Rendering to non-&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-non-html-mixin" id="id4"&gt;A non-&lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;mixin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-more-complex-example" id="id5"&gt;A more complex&amp;nbsp;example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id6"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have already written about the many advantages (&lt;span class="caps"&gt;DRY&lt;/span&gt;!) of using &lt;a class="reference external" href="http://spapas.github.io/2014/04/11/django-generic-formviews-for-objects/"&gt;CBVs in a previous article.&lt;/a&gt;
In this article I will present the correct (pythonic) way to allow a normal &lt;span class="caps"&gt;CBV&lt;/span&gt; to return non-&lt;span class="caps"&gt;HTML&lt;/span&gt; responses, like &lt;span class="caps"&gt;PDF&lt;/span&gt;, &lt;span class="caps"&gt;CSV&lt;/span&gt;, &lt;span class="caps"&gt;XSL&lt;/span&gt;&amp;nbsp;etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-are-cbvs-rendered"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;How are CBVs&amp;nbsp;rendered&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before proceeding, we need to understand how CBVs are rendered. By walking through the
class hierarchy in the &lt;a class="reference external" href="http://ccbv.co.uk/"&gt;&lt;span class="caps"&gt;CBV&lt;/span&gt; inspector&lt;/a&gt;, we can see that
all the normal Django CBVs (DetailView, CreateView, TemplateView etc) are using a mixin
named &lt;a class="reference external" href="http://ccbv.co.uk/projects/Django/1.7/django.views.generic.base/TemplateResponseMixin/"&gt;TemplateResponseMixin&lt;/a&gt; which defines a method named &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt;. This
is the method that is used for rendering the output of the Views. Let&amp;#8217;s take a look at
&lt;a class="reference external" href="http://ccbv.co.uk/projects/Django/1.7/django.views.generic.base/TemplateResponseMixin/"&gt;how it is defined&lt;/a&gt; (I&amp;#8217;ll remove the&amp;nbsp;comments):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TemplateResponseMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="n"&gt;response_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TemplateResponse&lt;/span&gt;
  &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;content_type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_template_names&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_template_names&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ImproperlyConfigured&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="s"&gt;&amp;quot;TemplateResponseMixin requires either a definition of &amp;quot;&lt;/span&gt;
              &lt;span class="s"&gt;&amp;quot;&amp;#39;template_name&amp;#39; or an implementation of &amp;#39;get_template_names()&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This method will try to find out which html template should be used to render the View
(using the  &lt;tt class="docutils literal"&gt;get_template_names&lt;/tt&gt; method and template_name attribute of the mixin) and
then render this view by instantiating an instance of the &lt;tt class="docutils literal"&gt;TemplateResponse&lt;/tt&gt; class
(as defined in the &lt;tt class="docutils literal"&gt;response_class&lt;/tt&gt; attribute)
and passing the request, template, context and other response_args to&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://github.com/django/django/blob/master/django/template/response.py"&gt;TemplateResponse&lt;/a&gt; class which is instantiated in the &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method
inherits from a normal &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt; and is used to render
the template passed to it as a&amp;nbsp;parameter.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="rendering-to-non-html"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Rendering to non-&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;From the previous discussion we can conclude that if your non-&lt;span class="caps"&gt;HTML&lt;/span&gt; response &lt;em&gt;needs&lt;/em&gt;
a template then you just need to create a subclass of &lt;tt class="docutils literal"&gt;TemplateResponse&lt;/tt&gt; and
assign it to the &lt;tt class="docutils literal"&gt;response_class&lt;/tt&gt; attribute (and also change the &lt;tt class="docutils literal"&gt;content_type&lt;/tt&gt;
attribute). On the other hand, if your non-&lt;span class="caps"&gt;HTML&lt;/span&gt; respond does not need a template
to be rendered then you have to override &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; completely
(since the template parameter does not need to be passed now) and either define
a subclass of HttpResponse or do the rendering in the&amp;nbsp;render_to_response.&lt;/p&gt;
&lt;p&gt;Since almost always you won&amp;#8217;t need a template to create a non-&lt;span class="caps"&gt;HTML&lt;/span&gt; view and because
I believe that the solution is &lt;span class="caps"&gt;DRY&lt;/span&gt;-enough by implementing the rendering code to
the &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method (&lt;em&gt;without&lt;/em&gt; subclassing &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt;) I will
implement a mixin that does exactly&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;Subclassing &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt; will not make our design more &lt;span class="caps"&gt;DRY&lt;/span&gt; because for every
subclass of &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt; the &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method would also need to
be modified (by subclassing &lt;tt class="docutils literal"&gt;TemplateResponseMixin) to instantiate the subclass of ``HttpResponse&lt;/tt&gt; with the correct parameters.
For instance, the existing &lt;tt class="docutils literal"&gt;TemplateResponseMixin&lt;/tt&gt; cannot be used if the subclass
of &lt;tt class="docutils literal"&gt;HttpResponse&lt;/tt&gt; does not take a template as a parameter (solutions like
passing None to the template parameter are signals of bad&amp;nbsp;design).&lt;/p&gt;
&lt;p&gt;In any case, changing just the &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method using a Mixin is in my opinion the best solution
to the above problem.
A &lt;a class="reference external" href="http://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful"&gt;Mixin&lt;/a&gt; is a simple class that can be used to extend other classes either by overriding functionality of the base class or
by adding extra features. Django CBVs use various &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/"&gt;mixins&lt;/a&gt; to extend the base Views and add&amp;nbsp;functionality.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-non-html-mixin"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;A non-&lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;mixin&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So, a basic skeleton for our mixin would be something like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NonHtmlResponseMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hello, world&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The previous mixin overrides the render_to_response method to just return the text &amp;quot;Hello, world&amp;quot;. For instance
we could define the following&amp;nbsp;class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DummyTextResponseView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NonHtmlResponseMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TemplateView&lt;/span&gt;&lt;span class="p"&gt;,):&lt;/span&gt;
  &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which can be added as a route to &lt;tt class="docutils literal"&gt;urls.py&lt;/tt&gt; (using the &lt;tt class="docutils literal"&gt;as_view&lt;/tt&gt; method) and will always return the &amp;quot;Hello, world&amp;quot;&amp;nbsp;text.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s something more complicated: A Mixin that can be used along with a DetailView and will output the properties of the
object as&amp;nbsp;text:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextPropertiesResponseMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/plain; charset=utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;{0}: {1}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="nb"&gt;unicode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__dict__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and can be used like&amp;nbsp;this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextPropertiesDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TextPropertiesResponseMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FooDetailView&lt;/span&gt;&lt;span class="p"&gt;,):&lt;/span&gt;
  &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above mixin will use the get_object() method of the DetailView to get the object and then output
it as text. We can create similar mixins that will integrate with other types of CBVs, for instance
to export a ListView as an &lt;span class="caps"&gt;CSV&lt;/span&gt; or generate an png from a DetailView of an Image&amp;nbsp;file.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-more-complex-example"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;A more complex&amp;nbsp;example&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous examples all built upon an existing view (either a TemplateView, a DetailView or a ListView).
However, an existing view that will fit our requirements won&amp;#8217;t always be available. For instance,
sometimes I want to export data from my database using a raw &lt;span class="caps"&gt;SQL&lt;/span&gt; query. Also I&amp;#8217;d like to be able to easily
export this data as csv or&amp;nbsp;excel.&lt;/p&gt;
&lt;p&gt;First of all, we need to define a view that will inherit from &lt;tt class="docutils literal"&gt;View&lt;/tt&gt; and export the data as a &lt;span class="caps"&gt;CSV&lt;/span&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;unicodecsv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CsvRawSqlExportView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;select 1+1&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;res&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
          &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
              &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;

      &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generate_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/plain; charset=utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Content-Disposition&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;attachment; filename=export.csv&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unicodecsv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above View has three attributes:
* sql, which is a string with the raw sql that will be executed
* headers, which is an array with the names of each header of the resulting data
* params, which is an array with parameters that may need to be passed to the&amp;nbsp;query&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;get&lt;/tt&gt; method executes the query and passes the result to &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt;
using a generator.  The &lt;tt class="docutils literal"&gt;render_to_response&lt;/tt&gt; method instantiates an HttpResponse
object with the correct attributes and writes the &lt;span class="caps"&gt;CSV&lt;/span&gt; to the response object using&amp;nbsp;unicodecsv.&lt;/p&gt;
&lt;p&gt;We can now quickly create a route that will export data from the users&amp;nbsp;table:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;r&amp;#39;^raw_export_users/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CsvRawSqlExportView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;select id, username from auth_user&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;raw_export_users&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If instead of &lt;span class="caps"&gt;CSV&lt;/span&gt; we wanted to export to &lt;span class="caps"&gt;XLS&lt;/span&gt; (using xlwt), we&amp;#8217;d just need to create a&amp;nbsp;Mixin:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XlsRawSqlResponseMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;application/ms-excel&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Content-Disposition&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;attachment; filename=export.xls&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;wb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xlwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Workbook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
              &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
          &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
              &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and create a View that inherits from &lt;tt class="docutils literal"&gt;CsvRawSqlExportView&lt;/tt&gt; and uses the above&amp;nbsp;mixin:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XlsRawSqlExportView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;XlsRawSqlResponseMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CsvRawSqlExportView&lt;/span&gt; &lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and route to that view to get the &lt;span class="caps"&gt;XLS&lt;/span&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;r&amp;#39;^raw_export_users/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XlsRawSqlExportView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;select id, username from auth_user&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;raw_export_users&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the above techniques we can define CBVs that will output their content in various content types
beyond &lt;span class="caps"&gt;HTML&lt;/span&gt;. This will help us write write clean and &lt;span class="caps"&gt;DRY&lt;/span&gt;&amp;nbsp;code.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 15 Sep 2014 14:20:00 +0300</pubDate><guid>tag:spapas.github.io,2014-09-15:2014/09/15/django-non-html-responses/</guid><category>django</category><category>python</category><category>cbv</category><category>class-based-views</category></item><item><title>Implementing a simple, Heroku-hosted REST service using Flask and mongoDB</title><link>http://spapas.github.io/2014/06/30/rest-flask-mongodb-heroku/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#requirements" id="id2"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#implementing-the-rest-service" id="id3"&gt;Implementing the &lt;span class="caps"&gt;REST&lt;/span&gt;&amp;nbsp;service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#testing-it-locally" id="id4"&gt;Testing it&amp;nbsp;locally&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#deploying-to-heroku" id="id5"&gt;Deploying to&amp;nbsp;Heroku&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the following, I will describe how I used &lt;a class="reference external" href="http://flask.pocoo.org/"&gt;Flask&lt;/a&gt;, a very nice web &lt;em&gt;microframework&lt;/em&gt; for python along  with &lt;a class="reference external" href="http://www.mongodb.org/"&gt;mongoDB&lt;/a&gt;, the most
popular No-&lt;span class="caps"&gt;SQL&lt;/span&gt; database to implement a simple &lt;span class="caps"&gt;REST&lt;/span&gt; service that was hosted on &lt;a class="reference external" href="https://dashboard.heroku.com/apps"&gt;Heroku&lt;/a&gt;. This &lt;span class="caps"&gt;REST&lt;/span&gt; service would get readings from
a number of sensors from an Android&amp;nbsp;device.&lt;/p&gt;
&lt;p&gt;I chose Flask instead of Django mainly because the &lt;span class="caps"&gt;REST&lt;/span&gt; service that I needed to implement would be very simple and most of
the Django bells and whistles (&lt;span class="caps"&gt;ORM&lt;/span&gt;, auth, admin, etc) wouldn&amp;#8217;t be needed anyway. Also, Flask is much quicker to set-up than
Django since almost everything (views, urls, etc) can be put inside one python&amp;nbsp;module.&lt;/p&gt;
&lt;p&gt;Concerning the choice of a NoSQL persistance solution (mongoDB), I wanted to have a table (or collection as it is called in the
mongoDB world) of readings from the sensor. Each reading would just have a timestamp and various other
arbitrary data depending on the type of the reading, so saving it as a &lt;span class="caps"&gt;JSON&lt;/span&gt; document in a NoSQL database is a good&amp;nbsp;solution.&lt;/p&gt;
&lt;p&gt;Finally, all the above will be deployed to Heroku which offers some great services for deploying python code in the&amp;nbsp;cloud.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="requirements"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Requirements&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I propose creating a file named &lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt; that will host the required packages for your project, so you will be
able to setup your projects after creating a virtual environment with &lt;a class="reference external" href="http://virtualenv.readthedocs.org/en/latest/"&gt;virtualenv&lt;/a&gt; just by running &lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;-r&lt;/span&gt; requirements.txt&lt;/tt&gt;.
Also, the requirements.txt is required for deploying python to&amp;nbsp;Heroku.&lt;/p&gt;
&lt;p&gt;So, for my case, the contents of requirements.txt are the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
Flask==0.10.1
Flask-PyMongo==0.3.0
Flask-RESTful==0.2.12
Jinja2==2.7.3
MarkupSafe==0.23
Werkzeug==0.9.6
aniso8601==0.82
gunicorn==19.0.0
itsdangerous==0.24
pymongo==2.7.1
pytz==2014.4
six==1.7.2
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Flask-PyMongo is a simple wrapper for Flask around pymongo which is the python mongoDB&amp;nbsp;driver.&lt;/li&gt;
&lt;li&gt;Flask-RESTful is a simple library for creating &lt;span class="caps"&gt;REST&lt;/span&gt; APIs - it needs aniso8601 and&amp;nbsp;pytz.&lt;/li&gt;
&lt;li&gt;Jinja2 is the template library for Flask (we won&amp;#8217;t use it but it is required by Flask installation) - it needs&amp;nbsp;MarkupSafe.&lt;/li&gt;
&lt;li&gt;Werkzeug is a &lt;span class="caps"&gt;WSGI&lt;/span&gt; utility library - required by&amp;nbsp;Flask&lt;/li&gt;
&lt;li&gt;gunicorn is a &lt;span class="caps"&gt;WSGI&lt;/span&gt; &lt;span class="caps"&gt;HTTP&lt;/span&gt; server - needed for deployment to&amp;nbsp;Heroku&lt;/li&gt;
&lt;li&gt;itsdangerous is used to sign data for usage in untrusted&amp;nbsp;environments&lt;/li&gt;
&lt;li&gt;six is the python 2/3 compatibility&amp;nbsp;layer&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="implementing-the-rest-service"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Implementing the &lt;span class="caps"&gt;REST&lt;/span&gt;&amp;nbsp;service&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of using just one single file for our Flask web application, we will create a python module to contain it and a
file named &lt;tt class="docutils literal"&gt;runserver.py&lt;/tt&gt; that will start a local development server to test&amp;nbsp;it:&lt;/p&gt;
&lt;p&gt;So, in the same folder as the &lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt; create a folder named &lt;tt class="docutils literal"&gt;flask_rest_service&lt;/tt&gt; and in there put
two files: &lt;tt class="docutils literal"&gt;__init__.py&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;resources.py&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;__init__.py&lt;/tt&gt; initializes our Flask application, our mongoDB connection and our Flask-RESTful&amp;nbsp;api:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import os
from flask import Flask
from flask.ext import restful
from flask.ext.pymongo import PyMongo
from flask import make_response
from bson.json_util import dumps

MONGO_URL = os.environ.get('MONGO_URL')
if not MONGO_URL:
    MONGO_URL = &amp;quot;mongodb://localhost:27017/rest&amp;quot;;

app = Flask(__name__)

app.config['MONGO_URI'] = MONGO_URL
mongo = PyMongo(app)

def output_json(obj, code, headers=None):
    resp = make_response(dumps(obj), code)
    resp.headers.extend(headers or {})
    return resp

DEFAULT_REPRESENTATIONS = {'application/json': output_json}
api = restful.Api(app)
api.representations = DEFAULT_REPRESENTATIONS

import flask_rest_service.resources
&lt;/pre&gt;
&lt;p&gt;So what happens here? After the imports, we check if we have a MONGO_URL environment variable. This is
how we set options in Heroku. If such option does not exist in the environment then we are in our
development environment so we set it to the localhost (we must have a running mongoDB installation in
our dev&amp;nbsp;environment).&lt;/p&gt;
&lt;p&gt;In the next lines, we initialize our Flask application and our mongoDB connection (pymongo
uses a &lt;tt class="docutils literal"&gt;MONGO_URI&lt;/tt&gt; configuration option to know the database &lt;span class="caps"&gt;URI&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;output_json&lt;/tt&gt; is used to dump the &lt;span class="caps"&gt;BSON&lt;/span&gt; encoded mongoDB objects to &lt;span class="caps"&gt;JSON&lt;/span&gt; and was borrowed from
&lt;a class="reference external" href="http://blog.alienretro.com/using-mongodb-with-flask-restful/"&gt;alienretro&amp;#8217;s blog&lt;/a&gt; &amp;#8212; we initialize our restful &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; with this&amp;nbsp;function.&lt;/p&gt;
&lt;p&gt;Finally, we import the &lt;tt class="docutils literal"&gt;resources.py&lt;/tt&gt; module which actually defines our &lt;span class="caps"&gt;REST&lt;/span&gt;&amp;nbsp;resources.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import json
from flask import request, abort
from flask.ext import restful
from flask.ext.restful import reqparse
from flask_rest_service import app, api, mongo
from bson.objectid import ObjectId

class ReadingList(restful.Resource):
    def __init__(self, *args, **kwargs):
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('reading', type=str)
        super(ReadingList, self).__init__()

    def get(self):
        return  [x for x in mongo.db.readings.find()]

    def post(self):
        args = self.parser.parse_args()
        if not args['reading']:
            abort(400)

        jo = json.loads(args['reading'])
        reading_id =  mongo.db.readings.insert(jo)
        return mongo.db.readings.find_one({&amp;quot;_id&amp;quot;: reading_id})


class Reading(restful.Resource):
    def get(self, reading_id):
        return mongo.db.readings.find_one_or_404({&amp;quot;_id&amp;quot;: reading_id})

    def delete(self, reading_id):
        mongo.db.readings.find_one_or_404({&amp;quot;_id&amp;quot;: reading_id})
        mongo.db.readings.remove({&amp;quot;_id&amp;quot;: reading_id})
        return '', 204


class Root(restful.Resource):
    def get(self):
        return {
            'status': 'OK',
            'mongo': str(mongo.db),
        }

api.add_resource(Root, '/')
api.add_resource(ReadingList, '/readings/')
api.add_resource(Reading, '/readings/&amp;lt;ObjectId:reading_id&amp;gt;')
&lt;/pre&gt;
&lt;p&gt;Here we define three &lt;tt class="docutils literal"&gt;Resource&lt;/tt&gt; classes and add them to our previously defined &lt;tt class="docutils literal"&gt;api&lt;/tt&gt;: &lt;tt class="docutils literal"&gt;Root&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;Reading&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;ReadingList&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;Root&lt;/tt&gt; just returns a dictionary with an &lt;span class="caps"&gt;OK&lt;/span&gt; status and some info on our mongodb&amp;nbsp;connection.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;Reading&lt;/tt&gt; has gets an ObjectId
(which is the mongodb primary key) as a parameter and depending on the &lt;span class="caps"&gt;HTTP&lt;/span&gt; operation, it returns the reading with that
id when receiving an &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/tt&gt; and deletes the reading with that id when receiving an &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;DELETE&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;ReadingList&lt;/tt&gt; will return all readings when receiving an &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/tt&gt; and will create a new reading when
receiving an &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;POST&lt;/span&gt;&lt;/tt&gt; The &lt;tt class="docutils literal"&gt;post&lt;/tt&gt; function uses the parser defined in &lt;tt class="docutils literal"&gt;__init__&lt;/tt&gt; which requires
a &lt;tt class="docutils literal"&gt;reading&lt;/tt&gt; parameter with the actual reading to be&amp;nbsp;inserted.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="testing-it-locally"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Testing it&amp;nbsp;locally&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to run the development server, you will need to install and start mongodb locally which is beyond the scope of this post. After that
create a file named &lt;tt class="docutils literal"&gt;runserver.py&lt;/tt&gt; in the same folder as with the &lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt;
and the &lt;tt class="docutils literal"&gt;flask_rest_service&lt;/tt&gt; folder. The contents of this file should&amp;nbsp;be:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
from flask_rest_service import app
app.run(debug=True)
&lt;/pre&gt;
&lt;p&gt;When you run this file with &lt;tt class="docutils literal"&gt;python runserver.py&lt;/tt&gt; you should be able top visit your rest service at &lt;a class="reference external" href="http://localhost:5000"&gt;http://localhost:5000&lt;/a&gt; and get
an &amp;quot;&lt;span class="caps"&gt;OK&lt;/span&gt;&amp;quot;&amp;nbsp;status.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="deploying-to-heroku"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Deploying to&amp;nbsp;Heroku&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To deploy to Heroku, you must create a &lt;tt class="docutils literal"&gt;Procfile&lt;/tt&gt; that contains the workers of your application. In our case, the
&lt;tt class="docutils literal"&gt;Procfile&lt;/tt&gt; should contain the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
web: gunicorn flask_rest_service:app
&lt;/pre&gt;
&lt;p&gt;Also, you should add a .gitignore file with the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
*.pyc
&lt;/pre&gt;
&lt;p&gt;Finally, to deploy your application to Heroku you can follow the instructions here: &lt;a class="reference external" href="https://devcenter.heroku.com/articles/getting-started-with-python"&gt;https://devcenter.heroku.com/articles/getting-started-with-python&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Initialize a git repository and commit&amp;nbsp;everything:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
git init
git add .
git commit -m
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Create a new Heroku application (after logging in to heroku with &lt;tt class="docutils literal"&gt;heroku login&lt;/tt&gt;) and set the MONGO_URL environment variable (of course you have to obtain ths MONGO_URL variable for your heroku envirotnment by adding a mongoDB&amp;nbsp;database):&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
heroku create
heroku config:set MONGO_URL=mongodb://user:pass&amp;#64;mongoprovider.com:27409/rest
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;And finally push your master branch to the heroku remote&amp;nbsp;repository:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
git push heroku master
&lt;/pre&gt;
&lt;p&gt;If everything went ok you should be able to start a worker for your application, check that the worker is running, and finally visit&amp;nbsp;it:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
heroku ps:scale web=1
heroku ps
heroku open
&lt;/pre&gt;
&lt;p&gt;If everything was ok you should see an status-&lt;span class="caps"&gt;OK&lt;/span&gt; &lt;span class="caps"&gt;JSON&lt;/span&gt;&amp;nbsp;!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 30 Jun 2014 15:23:00 +0300</pubDate><guid>tag:spapas.github.io,2014-06-30:2014/06/30/rest-flask-mongodb-heroku/</guid><category>flask</category><category>mongodb</category><category>heroku</category><category>python</category><category>rest</category></item><item><title>Django generic FormViews for objects</title><link>http://spapas.github.io/2014/04/11/django-generic-formviews-for-objects/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-quick-introduction-to-the-formview" id="id2"&gt;A quick introduction to the &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-quick-introduction-to-the-singleobjectmixin" id="id3"&gt;A quick introduction to the &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#being-generic-and-dry" id="id4"&gt;Being generic and &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#being-more-generic-and-dry" id="id5"&gt;Being more generic and &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#other-options" id="id6"&gt;Other&amp;nbsp;options&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We recently needed to create a number of views for changing the status of an Application model instance for our organization.
An Application model instance can be filled and then cancelled, submitted, acceptted etc - for each of these status changes a form should be
presented to the user. When the user submits the form the status of the Application will be&amp;nbsp;changed.&lt;/p&gt;
&lt;p&gt;To implement the above requirement we created a generic FormView that acts on the specific model instance. This
used two basic &lt;span class="caps"&gt;CBV&lt;/span&gt; components: The &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; for the form manipulation and the &lt;tt class="docutils literal"&gt;SingleObjectMixing&lt;/tt&gt; for the
object&amp;nbsp;handling.&lt;/p&gt;
&lt;p&gt;Django &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.6/topics/class-based-views/"&gt;Class Based Views&lt;/a&gt; (CBVs) can be used to create reusable Views using normal class inheritance. Most
people use the well-known &lt;tt class="docutils literal"&gt;CreateView&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;UpdateView&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;DetailView&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;ListView&lt;/tt&gt;, however, as we
will see below, the &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; will help us write &lt;span class="caps"&gt;DRY&lt;/span&gt;&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;I have to notice here that an invaluable tool to help you understanding CBVs is the &lt;a class="reference external" href="http://ccbv.co.uk/"&gt;&lt;span class="caps"&gt;CBV&lt;/span&gt; inspector&lt;/a&gt; which
has a nice web interface for browsing the &lt;span class="caps"&gt;CBV&lt;/span&gt; hierarchies, attributes and&amp;nbsp;methods.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-quick-introduction-to-the-formview"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;A quick introduction to the &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A simple &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; can be defined like this (&lt;a class="reference external" href="http://ccbv.co.uk/projects/Django/1.6/django.views.generic.edit/FormView/"&gt;&lt;span class="caps"&gt;CBV&lt;/span&gt; FormView&lt;/a&gt;):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class MyFormView(FormView):
  form_class = forms.MyFormView
  template_name = 'my_template.html'
&lt;/pre&gt;
&lt;p&gt;The above can be used in urls.py like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
urlpatterns = patterns('',
  url(r'^my_formview/$', views.MyFormView.as_view() , name='my_formview' ),
&lt;/pre&gt;
&lt;p&gt;This will present a form to the user when he visits the &lt;tt class="docutils literal"&gt;my_formview&lt;/tt&gt;  url &amp;#8212; however this form won&amp;#8217;t do anything. To allow
the form to actually do something when it&amp;#8217;s been submitted we need to override the &lt;tt class="docutils literal"&gt;form_valid&lt;/tt&gt; method.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
def form_valid(self, form):
    value = form.cleaned_data['value']
    messages.info(self.request, &amp;quot;MyForm submitted with value {0}!&amp;quot;.format(value) )
    return HttpResponseRedirect( reverse('my_formview') )
&lt;/pre&gt;
&lt;p&gt;As you can see the submitted form is passed in the method and can be used to receive its &lt;tt class="docutils literal"&gt;cleaned_data&lt;/tt&gt;. The &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt;
has various other options for instance a &lt;tt class="docutils literal"&gt;form_invalid&lt;/tt&gt; method, an &lt;tt class="docutils literal"&gt;initial&lt;/tt&gt; attribute to set the initial values for the form&amp;nbsp;etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-quick-introduction-to-the-singleobjectmixin"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;A quick introduction to the &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt; adds a number of attributes &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; methods to a view that can be used for object manipulation. The
most important ones is the &lt;tt class="docutils literal"&gt;model&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;queryset&lt;/tt&gt; attributes and the &lt;tt class="docutils literal"&gt;get_queryset&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;get_object()&lt;/tt&gt;. To use
the &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt; in your &lt;span class="caps"&gt;CBV&lt;/span&gt; just add it to the list of the classes to inherit from and define either the
&lt;tt class="docutils literal"&gt;model&lt;/tt&gt; or the &lt;tt class="docutils literal"&gt;queryset&lt;/tt&gt; attribute. After that you may pass a &lt;tt class="docutils literal"&gt;pk&lt;/tt&gt; parameter to your view and you will get an
&lt;tt class="docutils literal"&gt;object&lt;/tt&gt; context variable in the template with the selected&amp;nbsp;object!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="being-generic-and-dry"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Being generic and &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can more or less now understand how we should use &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt; to generate our
generic &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; for acting on objects: Our &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; should &lt;em&gt;get&lt;/em&gt; the object using the &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt;
and change it when the form is submitted using the values from the form. A first implementation would be the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class GenericObjectFormView1(FormView, SingleObjectMixin):

    def form_valid(self, form):
        obj = self.get_object()
        obj.change_status(form)
        return HttpResponseRedirect( obj.get_absolute_url() )
&lt;/pre&gt;
&lt;p&gt;So our &lt;tt class="docutils literal"&gt;GenericObjectFormView1&lt;/tt&gt; class inherits from &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt;. The only thing that we have
to assure is that the Model we want to act on needs to implement a &lt;tt class="docutils literal"&gt;change_status&lt;/tt&gt; method which gets the &lt;tt class="docutils literal"&gt;form&lt;/tt&gt; and
changes the status of that object based on its value. For instance, two implementations can be the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class CancelObjectFormView(GenericObjectFormView1):
    template_name = 'cancel.html'
    form_class = forms.CancelForm
    model = models.Application

class SubmitObjectFormView(GenericObjectFormView1):
    template_name = 'submit.html'
    form_class = forms.SubmitForm
    model = models.Application
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="being-more-generic-and-dry"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Being more generic and &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous implementation has two&amp;nbsp;problems:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;What happens if the status of the object should not be changed even if the form &lt;em&gt;is&lt;/em&gt;&amp;nbsp;valid?&lt;/li&gt;
&lt;li&gt;We shouldn&amp;#8217;t need to create a new template for every new &lt;tt class="docutils literal"&gt;GenericObjectFormView&lt;/tt&gt; since all these templates will just output the object information, ask a question for the status change and output the&amp;nbsp;form.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;#8217;s write a new version of our GenericObjectFormView that actually resolves&amp;nbsp;these:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class GenericObjectFormView2(FormView, SingleObjectMixin):
    template_name = 'generic_formview.html'
    ok_message = ''
    not_ok_message = ''
    title = ''
    question =''

    def form_valid(self, form):
        obj = self.get_object()
        r = obj.change_status(form)
        if r:
            messages.info(self.request, self.yes_message)
        else:
            messages.info(self.request, self.not_ok_message)
        return HttpResponseRedirect( obj.get_absolute_url() )

    def get_context_data(self, **kwargs):
        context = super(GenericYesNoFormView, self).get_context_data(**kwargs)
        context['title'] = self.title
        context['question'] = self.question
        return context
&lt;/pre&gt;
&lt;p&gt;The above adds an ok and not ok message which will be outputed if the status can or cannot be changed. To accomplish this,
the &lt;tt class="docutils literal"&gt;change_status&lt;/tt&gt; method should now return a boolean value to mark if the action was ok or not. Also, a generic template
will now be used. This template has two placeholders: One for the title of the page (&lt;tt class="docutils literal"&gt;title&lt;/tt&gt; attribute) and one for the
question asked to the user (&lt;tt class="docutils literal"&gt;question&lt;/tt&gt; attribute). Now we can use it like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class CancelObjectFormView(GenericObjectFormView2):
    form_class = forms.CancelForm
    model = models.Application
    ok_message = 'Cancel success!'
    not_ok_message = 'Not able to cancel!'
    title = 'Cancel an object'
    question = 'Do you want to cancel this object?'

class SubmitObjectFormView(GenericObjectFormView2):
    form_class = forms.SubmitForm
    model = models.Application
    ok_message = 'Submit  ok'
    not_ok_message = 'Cannot submit!'
    title = 'Submit an object'
    question ='Do you want to submit this object?'
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="other-options"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6"&gt;Other&amp;nbsp;options&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ve just got a glimpse of how we can use CBVs to increase the DRYness of our Django applications. There are various
extra things that we can add to our &lt;tt class="docutils literal"&gt;GenericObjectFormView2&lt;/tt&gt; as attributes which will be defined by inheriting
classes. Some ideas is to check if the current user actually has access to modify the object (hint: override the
&lt;tt class="docutils literal"&gt;get_object&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;SingleObjectMixin&lt;/tt&gt;) or render the form diffirently depending on the current user (hint:
override the &lt;tt class="docutils literal"&gt;get_form_kwargs&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt;).&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Fri, 11 Apr 2014 10:23:00 +0300</pubDate><guid>tag:spapas.github.io,2014-04-11:2014/04/11/django-generic-formviews-for-objects/</guid><category>django</category><category>python</category><category>cbv</category><category>class-based-views</category></item><item><title>A Wagtail tutorial</title><link>http://spapas.github.io/2014/02/13/wagtail-tutorial/</link><description>&lt;p&gt;&lt;a href="http://wagtail.io"&gt;Wagtail&lt;/a&gt; is a new Open Source &lt;a href="https://www.djangoproject.com"&gt;Django&lt;/a&gt;-based &lt;span class="caps"&gt;CMS&lt;/span&gt;. In this 20 minute tutorial we will see how you can create a blog from scratch using Wagtail. If you want to see some more examples of usage please take a look at the &lt;a href="https://github.com/torchbox/wagtaildemo"&gt;wagtaildemo&lt;/a&gt; GitHub&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;To follow this tutorial you will need to have &lt;a href="http://python.org/"&gt;Python&lt;/a&gt; 2.7 installed with a working version of &lt;a href="https://pypi.python.org/pypi/pip"&gt;pip&lt;/a&gt; and &lt;a href="https://pypi.python.org/pypi/virtualenv"&gt;virtualenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: The result of this tutorial has been deployed to &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;: &lt;a href="http://gentle-refuge-2590.herokuapp.com/"&gt;http://gentle-refuge-2590.herokuapp.com/&lt;/a&gt; - you may visit the &lt;a href="http://gentle-refuge-2590.herokuapp.com/admin/"&gt;admin site&lt;/a&gt; and login with root / 123 to play with Wagtail! Please don&amp;#8217;t do anything naughty !!! Also, notice that &lt;a href="https://devcenter.heroku.com/articles/dynos#isolation-and-security"&gt;because of how Heroku works&lt;/a&gt; you won&amp;#8217;t be able to upload&amp;nbsp;anything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 08/09/2015: This tutorial has been written during the first days of Wagtail, when documentation and tutorials about it were sparce; right now it should be considered by all accounts obsolete and &lt;em&gt;not&lt;/em&gt; be followed! Instead, you should read the official (and very well written) tutorial @ &lt;a href="http://docs.wagtail.io/en/v1.0/getting_started/tutorial.html"&gt;http://docs.wagtail.io/en/v1.0/getting_started/tutorial.html&lt;/a&gt; in the official Wagtail&amp;nbsp;documentation!&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Installing the wagtail&amp;nbsp;dependencies&lt;/h2&gt;
&lt;p&gt;It is recomended to create a new virtual environment that will host the wagtail tutorial. After you have changed to the virtual environment you will need to installl the Wagtail requirements. Create a file named &lt;code&gt;requirements.txt&lt;/code&gt; containing the&amp;nbsp;following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;Django==1.6.2
South==1.0.0
django-compressor==1.4
django-modelcluster==0.3
-e git://github.com/torchbox/wagtail.git#egg=wagtail
django-taggit==0.11.2
django-libsass==0.2
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and run
&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;.  If you use Microsoft Windows you &lt;em&gt;will&lt;/em&gt; experience problems with Pillow and lxml. Please download the 
installation executables from https://pypi.python.org/pypi/Pillow/2.3.0 and https://pypi.python.org/pypi/lxml/3.3.1, install 
them using &lt;code&gt;easy_install Pillow-2.3.0.x-py2.7.exe&lt;/code&gt; and &lt;code&gt;easy_install lxml-3.3.1.x-py2.7.exe&lt;/code&gt; (from inside your virtual environment) 
and then install the other requirements. Also please use the latest version of Wagtail (hosted on github) because it has some changes from 
the pypi (so &lt;em&gt;don&amp;#8217;t&lt;/em&gt; do a &lt;code&gt;pip install wagtail&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Unfortuanately, no official binaries for libsass (which is a django-libsass requirement) are (yet) available for Windows. I
have compiled a version for win32 and python 2.7 (which I use) using the &lt;a href="http://www.confusedbycode.com/articles/compiling-python-modules.html"&gt;instructions found here&lt;/a&gt;. You can download this version 
&lt;a href="http://spapas.github.io/images/libsass-0.3.0-cp27-none-win32.whl"&gt;as a wheel package&lt;/a&gt;. Notice that because libsass was compiled with &lt;span class="caps"&gt;VC&lt;/span&gt; Express 2013
you should also install the &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=40784"&gt;Visual C++ 2013 redistributable&lt;/a&gt; package from&amp;nbsp;Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Please use it at your own risk&amp;nbsp;!!!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To install &lt;a href="http://pythonwheels.com/"&gt;wheels&lt;/a&gt; you have to use a version of pip &amp;gt;= 1.4 (so do an &lt;code&gt;easy_install -U pip&lt;/code&gt; from your
virtual environment if you have a previous version) and then you can just do a normal &lt;code&gt;pip install libsass-0.3.0-cp27-none-win32.whl&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning no2:&lt;/strong&gt; More unfortuanately, there seem to be &lt;a href="https://github.com/torchbox/wagtail/issues/133"&gt;a number of issues&lt;/a&gt; with how libsass handles &lt;code&gt;@import&lt;/code&gt; statements
in Windows. Until this is fixed, Windows users are recommened to use the command line (Ruby) sass compiler. To use it, please
install Ruby in your system and then install sass with &lt;code&gt;gem install sass -v "&amp;gt;=3.3.0alpha" --pre&lt;/code&gt;. After that, in the &lt;code&gt;COMPRESS_PRECOMPILERS&lt;/code&gt; 
setting of your &lt;code&gt;settings.py&lt;/code&gt; (discussed in the next section), change the line &lt;code&gt;('text/x-scss', 'django_libsass.SassCompiler'),&lt;/code&gt; to 
&lt;code&gt;('text/x-scss', 'sass --scss  {infile} {outfile}'),&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Creating and configuring your&amp;nbsp;project&lt;/h2&gt;
&lt;p&gt;Wagtail has to &amp;#8220;live&amp;#8221; inside a normal Django project so you now may create a new Django project by&amp;nbsp;issuing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;python &amp;lt;PATH_OF_YOUR_VIRTUAL_ENV&amp;gt;/scripts/django-admin.py startproject wagtailtutorial
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you use Unix you can just run &lt;code&gt;django-admin.py&lt;/code&gt; etc however if you try to do the same in windows you
will find out that windows tries to run the .py file with the python executable that is assigned through
explorer (which of course is your main python installation) and &lt;em&gt;not&lt;/em&gt; through your path! That&amp;#8217;s why
all our commands will be in the form &lt;code&gt;python script.py&lt;/code&gt; to make sure that Windows picks the python
executable from your path (which, if you&amp;#8217;re inside the virtual enviroment will be the correct&amp;nbsp;one).&lt;/p&gt;
&lt;p&gt;Inside the &lt;code&gt;wagtailtutorial&lt;/code&gt; folder you will see a file named &lt;code&gt;manage.py&lt;/code&gt; and another folder named &lt;code&gt;wagtailtutorial&lt;/code&gt;. Inside this &lt;code&gt;wagtailtutorial&lt;/code&gt; folder you will find &lt;code&gt;settings.py&lt;/code&gt; and &lt;code&gt;urls.py&lt;/code&gt; which need to be&amp;nbsp;changed.&lt;/p&gt;
&lt;p&gt;Starting with &lt;code&gt;urls.py&lt;/code&gt;, remove everything and change it like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls.static&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RedirectView&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os.path&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtail_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailadmin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailadmin_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailimages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailimages_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailembeds&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailembeds_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtaildocs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin_urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtaildocs_admin_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtaildocs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtaildocs_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailsnippets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailsnippets_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailsearch.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;frontend&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailsearch_frontend_urls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailsearch_admin_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailusers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailusers_urls&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailredirects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailredirects_urls&lt;/span&gt;

&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autodiscover&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="c"&gt;# Signal handlers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailsearch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;register_signal_handlers&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;wagtailsearch_register_signal_handlers&lt;/span&gt;
&lt;span class="n"&gt;wagtailsearch_register_signal_handlers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^django-admin/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/images/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailimages_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/embeds/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailembeds_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/documents/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtaildocs_admin_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/snippets/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailsnippets_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/search/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailsearch_admin_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/users/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailusers_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/redirects/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailredirects_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^admin/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailadmin_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^search/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtailsearch_frontend_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^documents/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtaildocs_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;

    &lt;span class="c"&gt;# For anything not caught by a more specific rule above, hand over to&lt;/span&gt;
    &lt;span class="c"&gt;# Wagtail&amp;#39;s serving mechanism&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wagtail_urls&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.staticfiles.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;staticfiles_urlpatterns&lt;/span&gt;

    &lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;staticfiles_urlpatterns&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# tell gunicorn where static files are in dev mode&lt;/span&gt;
    &lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;images/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MEDIA_ROOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can se that there is a signal handler when a searchable thing is added or changed to handle indexing for search, normal django admin is mapped under /django-admin since /admin is use for Wagtail (of course you may map Wagtail wherever you&amp;#8217;d like), inclusion of various wagtail related urls and finally a Wagtail handling everything else. Finally there are some handlers for media and static&amp;nbsp;files.&lt;/p&gt;
&lt;p&gt;After that please change your &lt;code&gt;settings.py&lt;/code&gt; like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Django settings for wagtailtutorial project.&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;PROJECT_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;..&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;..&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DEBUG&lt;/span&gt;

&lt;span class="n"&gt;ADMINS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;MANAGERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ADMINS&lt;/span&gt;

&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;ENGINE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.db.backends.sqlite3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;NAME&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PROJECT_ROOT&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;/wagtailtutorial.db&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;USER&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;PASSWORD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;HOST&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;# Set to empty string for localhost.&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;PORT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c"&gt;# Set to empty string for default.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;CONN_MAX_AGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;  &lt;span class="c"&gt;# number of seconds database connections should persist for&lt;/span&gt;
&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;TIME_ZONE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Europe/London&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;LANGUAGE_CODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;en-gb&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;SITE_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;USE_I18N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;USE_L10N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;USE_TZ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PROJECT_ROOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;media&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/media/&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;STATIC_ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PROJECT_ROOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;static&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;STATIC_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/static/&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;STATICFILES_DIRS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;STATICFILES_FINDERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.staticfiles.finders.FileSystemFinder&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.staticfiles.finders.AppDirectoriesFinder&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;compressor.finders.CompressorFinder&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wq21wtjo3@d_qfjvd-#td!&lt;/span&gt;&lt;span class="si"&gt;%7g&lt;/span&gt;&lt;span class="s"&gt;fy2updj2z+nev^k$iy%=m4_tr&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;TEMPLATE_LOADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.template.loaders.filesystem.Loader&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.template.loaders.app_directories.Loader&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;MIDDLEWARE_CLASSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.common.CommonMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.sessions.middleware.SessionMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.csrf.CsrfViewMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.auth.middleware.AuthenticationMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.messages.middleware.MessageMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.middleware.clickjacking.XFrameOptionsMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailcore.middleware.SiteMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailredirects.middleware.RedirectMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;global_settings&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATE_CONTEXT_PROCESSORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;global_settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TEMPLATE_CONTEXT_PROCESSORS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.core.context_processors.request&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ROOT_URLCONF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wagtailtutorial.urls&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;WSGI_APPLICATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wagtailtutorial.wsgi.application&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATE_DIRS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c"&gt;# &amp;#39;django.contrib.sites&amp;#39;,  # Wagtail uses its own site management logic&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.messages&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.staticfiles&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;south&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;compressor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;taggit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;modelcluster&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailcore&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailadmin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtaildocs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailsnippets&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailusers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailimages&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailembeds&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailsearch&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wagtail.wagtailredirects&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="s"&gt;&amp;#39;tutorial&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;EMAIL_SUBJECT_PREFIX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;[wagtailtutorial] &amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;INTERNAL_IPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;10.0.2.2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;COMPRESS_PRECOMPILERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/x-scss&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django_libsass.SassCompiler&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Auth settings&lt;/span&gt;
&lt;span class="n"&gt;LOGIN_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.contrib.auth.views.login&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;LOGIN_REDIRECT_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wagtailadmin_home&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;LOGGING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;disable_existing_loggers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;filters&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;require_debug_false&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.utils.log.RequireDebugFalse&amp;#39;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;handlers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;mail_admins&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;level&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ERROR&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;filters&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;require_debug_false&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;django.utils.log.AdminEmailHandler&amp;#39;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;loggers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;django.request&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;handlers&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;mail_admins&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;level&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ERROR&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;&amp;#39;propagate&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;# WAGTAIL SETTINGS&lt;/span&gt;
&lt;span class="n"&gt;WAGTAIL_SITE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wagtailtutorial&amp;#39;&lt;/span&gt;

&lt;span class="c"&gt;# Override the search results template for wagtailsearch&lt;/span&gt;
&lt;span class="n"&gt;WAGTAILSEARCH_RESULTS_TEMPLATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;tutorial/search_results.html&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;WAGTAILSEARCH_RESULTS_TEMPLATE_AJAX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;tutorial/includes/search_listing.html&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;WAGTAILSEARCH_ES_INDEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;wagtailtutorial&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The most important thing to notice is that  the &lt;code&gt;INSTALLED_APPS&lt;/code&gt; contains the usual apps from django.*, &lt;a href="http://south.aeracode.org/"&gt;south&lt;/a&gt; for database migrations, &lt;a href="https://github.com/django-compressor/django-compressor"&gt;django-compressor&lt;/a&gt; to support compressing static files (and automatic translating from less to css), &lt;a href="https://github.com/alex/django-taggit"&gt;django-taggit&lt;/a&gt; to add support for tags, and &lt;a href="https://github.com/torchbox/django-modelcluster/"&gt;django-modelcluster&lt;/a&gt; which adds support from clusters (groups) of models. It also contains the wagtail.* applications and the tutorial application which is where we will create our blog. Also there are two Wagtail related middleware (one to add a site attribute to each request and one to hand redirects), configuring django-compressor to use &lt;code&gt;django_libsass&lt;/code&gt; to compile &lt;code&gt;less&lt;/code&gt; files, and some other, not so important Wagtail&amp;nbsp;settings.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s create the missing tutorial application by&amp;nbsp;issuing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;python manage.py startapp tutorial
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now we&amp;#8217;ll have a &lt;code&gt;tutorial&lt;/code&gt; folder waiting to define our blog structure inside the &lt;code&gt;wagtailtutorial&lt;/code&gt; folder!&lt;/p&gt;
&lt;h2&gt;Checking to see if everything&amp;nbsp;works&lt;/h2&gt;
&lt;p&gt;Before continuing with our blog creation let&amp;#8217;s make sure that everything works, first of all by generating the database&amp;nbsp;schema:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;python manage.py syncdb
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In the superuser question answer yes and add a superuser. Then you can run the migrations - however because there are some problems with the way SQLite3 runs migrations it is recommended to run the migrations in two&amp;nbsp;steps:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;python manage.py migrate &lt;span class="m"&gt;0001&lt;/span&gt; --all
python manage.py migrate
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Finally, you now may try&amp;nbsp;a&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;python manage.py runserver
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and visit &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt;. If everything worked fine you will get&amp;nbsp;a&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Welcome to your new Wagtail&amp;nbsp;site!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;page &amp;#8212; congratulations&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;The homepage is rather simple (for now!) but you may already navigate to http://127.0.0.1:8000/admin and from there, login to Wagtail admin with the superuser you created earlier. 
Now you may start experiencing Wagtail&amp;nbsp;! &lt;/p&gt;
&lt;p&gt;&lt;img alt="Wagtail admin index" src="http://spapas.github.io/images/wagtail-index.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Exploring Wagtail&amp;nbsp;admin&lt;/h2&gt;
&lt;p&gt;When you login to Wagtail admin you will see a menu at the left with the&amp;nbsp;options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explorer is used to actually manage the content of your&amp;nbsp;site&lt;/li&gt;
&lt;li&gt;Search is used for searching through your&amp;nbsp;content&lt;/li&gt;
&lt;li&gt;Images is used to manage your&amp;nbsp;images&lt;/li&gt;
&lt;li&gt;Documents is used to manage your&amp;nbsp;Documents&lt;/li&gt;
&lt;li&gt;Snippets is used for side bars&amp;nbsp;etc&lt;/li&gt;
&lt;li&gt;Users is used for User&amp;nbsp;management&lt;/li&gt;
&lt;li&gt;Redirects is used to redirect to a specific&amp;nbsp;page&lt;/li&gt;
&lt;li&gt;Editors picks is used to promote search&amp;nbsp;results&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of the previous, the one needing more explanation is Explorer: Clicking it you will see that a label named &amp;#8220;Welcome to your Wagtail site!&amp;#8221; will open. This is the root Page of your site. If you click at it you will go to the actions of this page. The actions you can do here is:
 - Add Child Page
 - Edit
 - View Live
 - Move
 - Delete
 -&amp;nbsp;Unpublish&lt;/p&gt;
&lt;p&gt;The Pages (and more generally the Content) of Wagtail are Django Models that are saved through a Tree hierarchy. However, if you click &amp;#8220;Add Child Page&amp;#8221; you won&amp;#8217;t be able to add anything because you must create your own Page types (we will see how it is done in the next&amp;nbsp;section). &lt;/p&gt;
&lt;p&gt;When you click edit you will be able to edit the parts of the page (each part is a normal Field of the model). Also, you will see that the form is split into two tabs: Content and Promote. In the Content for instance you will see that the &amp;#8220;Welcome to your Wagtail site!&amp;#8221; has only a &amp;#8220;Title&amp;#8221; CharField. These are the fields that will be available to all Pages since &amp;#8220;Welcome to your Wagtail site!&amp;#8221; has a class of &lt;code&gt;Page&lt;/code&gt; from which every other page should inherit. After you finish editing a page you may save it as a draft, publish, sent it for moderation (if you don&amp;#8217;t have the rights to publish it)&amp;nbsp;etc.&lt;/p&gt;
&lt;h2&gt;Creating our&amp;nbsp;blog&lt;/h2&gt;
&lt;p&gt;Each of our Page types is a normal Django Model which inherits from &lt;code&gt;Page&lt;/code&gt;. Let&amp;#8217;s suppose that our posts should contain a title, a body and a created date. Add the following to &lt;code&gt;tutorials/models.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailcore.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailcore.fields&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RichTextField&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailadmin.edit_handlers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FieldPanel&lt;/span&gt;    

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RichTextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Post date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;search_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Blog Page&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;indexed_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;BlogPage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_panels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and run &lt;code&gt;python manage.py syncdb&lt;/code&gt; to create the &lt;code&gt;tutorial_blogpage&lt;/code&gt; table. &lt;/p&gt;
&lt;p&gt;Now, if you visit again the /admin and click on the &amp;#8220;Add Child Page&amp;#8221; action of &amp;#8220;Welcome to your new Wagtail Site!&amp;#8221; you will see the &amp;#8220;Blog Page&amp;#8221; page and after you click it you will be able to see a form with the Fields you defined &lt;em&gt;and&lt;/em&gt; title(title, body, date). The title is a field inherited from Page, along with the fields  in the Promote&amp;nbsp;tab. &lt;/p&gt;
&lt;p&gt;In our declaration of BlogPage we added three &lt;code&gt;FieldPanel&lt;/code&gt;s on its content_panes. A &lt;code&gt;FieldPanel&lt;/code&gt; is a special edit handler for each Field. That is why when you try to edit the body you will see a rich text toolbar that enables you to not only format text but also embed images, documents and even oembed links. If you hadn&amp;#8217;t included the &lt;code&gt;FieldPanel('body', classname="full")&lt;/code&gt; then you wouldn&amp;#8217;t see the rich text&amp;nbsp;editor.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Editing pages in Wagtail" src="http://spapas.github.io/images/wagtail-edit-page.png" /&gt;&lt;/p&gt;
&lt;p&gt;So now we can add as many posts as we&amp;nbsp;like! &lt;/p&gt;
&lt;p&gt;The time has come to take a look at our fine blog post: After we publish our page we click to the view live action&amp;nbsp;and&amp;#8230; &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TemplateDoesNotExist at&amp;nbsp;/hello-world/&lt;/p&gt;
&lt;p&gt;tutorial/blog_page.html&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:(&lt;/p&gt;
&lt;p&gt;A template seems to be missing &amp;#8212; actually we have totally forgotten about the presentation of our blog &amp;#8212; we&amp;#8217;ll talk about this in the next section&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;However, before going there we should also create an Index page type collecting our&amp;nbsp;posts. &lt;/p&gt;
&lt;p&gt;For this, we will change our &lt;code&gt;models.py&lt;/code&gt; to&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailcore.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Orderable&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailcore.fields&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RichTextField&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;wagtail.wagtailadmin.edit_handlers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FieldPanel&lt;/span&gt;  &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MultiFieldPanel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;InlinePanel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PageChooserPanel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;modelcluster.fields&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ParentalKey&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RichTextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Post date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;indexed_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;search_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Blog Page&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;BlogPage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_panels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;link_page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;wagtailcore.Page&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;panels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;PageChooserPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;link_page&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RelatedLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LinkFields&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Link title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;panels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;MultiFieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LinkFields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;panels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Link&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogIndexPageRelatedLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Orderable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RelatedLink&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ParentalKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;tutorial.BlogIndexPage&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;related_links&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogIndexPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;intro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;indexed_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;search_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Blog Index Page&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;BlogIndexPage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_panels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;FieldPanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;intro&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;full&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;InlinePanel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BlogIndexPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;related_links&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Related links&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;    
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The above adds a way to put &lt;code&gt;related_links&lt;/code&gt; to a &lt;code&gt;BlogIndexPage&lt;/code&gt; &amp;#8212; these related_links are the &lt;code&gt;BlogPage&lt;/code&gt;s that actually belong to the blog - so now, we can add a blog index page and add all our blog posts to&amp;nbsp;it!&lt;/p&gt;
&lt;p&gt;Now that we&amp;#8217;ve created the BlogPage and BlogIndexPage pages it&amp;#8217;s time to take a look at how we will actually display our&amp;nbsp;blog&amp;#8230;&lt;/p&gt;
&lt;h2&gt;Creating templates for &lt;em&gt;Page&lt;/em&gt;s&lt;/h2&gt;
&lt;p&gt;A normal Django template can be used to display each page type. Wagtail either generates automatically (by seperating underscors with capital letters in camelcase for instance BlogIndexPage -&amp;gt; blog_index_page) or you can use the template class attribute. Let&amp;#8217;s add a &lt;code&gt;templates&lt;/code&gt; foler within the &lt;code&gt;tutorial&lt;/code&gt; foler and add another folder named &lt;code&gt;tutorial&lt;/code&gt; inside &lt;code&gt;templates&lt;/code&gt; and ten add a file named &lt;code&gt;blog_index_page.html&lt;/code&gt; to &lt;code&gt;templates&lt;/code&gt; with the following content (you must have the following hierarchy &lt;code&gt;wagtailtutorial/tutorial/templates/tutorial/blog_index_page.html&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ self.title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        Intro: {{ self.intro }}
        &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        {% for rl in self.related_links.all %}
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ rl.title }}: &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;{{ rl.link_page.url }}&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ rl.link_page }}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        {% endfor %}
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So self is the context name of the  BlogPageIndex instance that is used to render this page. Beyond that, it&amp;#8217;s normal&amp;nbsp;django.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Rendering the Blog Index" src="http://spapas.github.io/images/wagtail-index-template.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now you can view your Blog Index &amp;#8212; however before clicking on a link to also view your posts add the template for your &lt;code&gt;BlogPost&lt;/code&gt; (&lt;code&gt;tutorial/blog_page.html&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;{% load rich_text %}
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ self.title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        Date: {{ self.date }}
        {{ self.body | richtext }}
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;    
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The extra thing here is the &lt;code&gt;richtext&lt;/code&gt; filter which renders a &lt;code&gt;RichTextField&lt;/code&gt; correctly. Of course the above templates are just examples - check &lt;code&gt;wagtaildemo&lt;/code&gt; for a much better template&amp;nbsp;design.&lt;/p&gt;
&lt;p&gt;Woo-hoo &amp;#8212; now I can totally start blogging !!!&amp;nbsp;\o/&lt;/p&gt;
&lt;p&gt;&amp;#8230;&lt;/p&gt;
&lt;p&gt;&amp;#8230;&lt;/p&gt;
&lt;p&gt;But &amp;#8230; when I go to 127.0.0.1:8000 it displays the ugly &amp;#8220;Welcome to your new Wagtail site!&amp;#8221;. I don&amp;#8217;t want to see that any more&amp;nbsp;!!!&lt;/p&gt;
&lt;p&gt;No problemo - check the next section of the tutorial&amp;nbsp;:)&lt;/p&gt;
&lt;h2&gt;Changing your home&amp;nbsp;page&lt;/h2&gt;
&lt;p&gt;Wagtail uses the concept of &lt;em&gt;sites&lt;/em&gt; to define groups of pages hosted in the &lt;em&gt;same&lt;/em&gt; server. To make more clear what site is, you have to use the good old django admin which can be found at &lt;code&gt;http://127.0.0.1:8000/django-admin/&lt;/code&gt;. Check the localhost[default] site entry: You will see that each site has a name, a root page (currently the &amp;#8220;Welcome to your new Wagtail site!&amp;#8221;) and an is_default check. So,  change the root page of the localhost site to your BlogIndexPage and go to &lt;code&gt;http://127.0.0.1:8000/&lt;/code&gt; &amp;#8230; Yes ! The blog is alive&amp;nbsp;:)&lt;/p&gt;
&lt;h2&gt;Where to go from&amp;nbsp;here&lt;/h2&gt;
&lt;p&gt;You are now ready to start adding more pages to your blog, adding functionality to it (don&amp;#8217;t forget that everything is just Django models and templates so you can
change it at will), or even creating a completely different kind of site by adding other Page types. For a more complete site with lots of examples please check 
&lt;a href="https://github.com/torchbox/wagtaildemo"&gt;wagtaildemo&lt;/a&gt;. There is
no complete documentation yet however you&amp;nbsp;can &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use the source&amp;nbsp;Luke!&lt;/p&gt;
&lt;/blockquote&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Thu, 13 Feb 2014 21:20:00 +0200</pubDate><guid>tag:spapas.github.io,2014-02-13:2014/02/13/wagtail-tutorial/</guid><category>wagtail</category><category>python</category><category>django</category></item><item><title>Django dynamic forms</title><link>http://spapas.github.io/2013/12/24/django-dynamic-forms/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#describing-a-django-form-in-json" id="id2"&gt;Describing a django form in &lt;span class="caps"&gt;JSON&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-the-form-fields" id="id3"&gt;Creating the form&amp;nbsp;fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-the-actual-form" id="id4"&gt;Creating the actual&amp;nbsp;form&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-the-dynamic-form" id="id5"&gt;Using the dynamic&amp;nbsp;form&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To define a form in django, a developer has to create a class which extends
&lt;tt class="docutils literal"&gt;django.forms.Form&lt;/tt&gt;
and has  a number of attributes extending from &lt;tt class="docutils literal"&gt;django.forms.Field&lt;/tt&gt;. This makes
it very easy for the developer to create static forms, but creating
dynamic forms whose fields can be changed depending on the data contributed by the
users of the application is not so&amp;nbsp;obvious.&lt;/p&gt;
&lt;p&gt;Of course, some people may argue that they can do whatever
they want just by spitting html input tags to their templates, however this totally violates
&lt;span class="caps"&gt;DRY&lt;/span&gt; and any serious django developer would prefer to write &lt;a class="reference external" href="http://thedailywtf.com/Articles/A_Case_of_the_MUMPS.aspx"&gt;&lt;span class="caps"&gt;MUMPS&lt;/span&gt;&lt;/a&gt; than creating
html&amp;nbsp;dynamically.&lt;/p&gt;
&lt;p&gt;The implementation I will present here had been developed for an old project: In that
project there was a number of services which could be edited dynamically by the
moderators. For each service, the moderators would generate a questionnaire to
get input from the users which would be defined  using &lt;span class="caps"&gt;JSON&lt;/span&gt;. When the users needed
to submit information for each service, a dynamic django form would be generated
from this &lt;span class="caps"&gt;JSON&lt;/span&gt; and the answers would be saved to no-&lt;span class="caps"&gt;SQL&lt;/span&gt; database like&amp;nbsp;MongoDB.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="describing-a-django-form-in-json"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Describing a django form in &lt;span class="caps"&gt;JSON&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;span class="caps"&gt;JSON&lt;/span&gt; described django form is just an array of field &lt;span class="caps"&gt;JSON&lt;/span&gt; objects. Each field
object  has three required attributes: name which is the keyword of the field, label which is
how the label of the field and type which is the type of the input of that field. The
supported types are text, textarea, integer, radio, select, checkbox. Now, depending
on the type of the field, there could be also some more required attributes, for instace
text has a max_length attribute and select has a choices attribute (which is an array
of name/value objects). Also there are two optional attributes,
required with a default value of False and help_text with a default value of&amp;nbsp;&amp;#8221;.&lt;/p&gt;
&lt;p&gt;As you can understand these map one by one to the corresponding attributes of the
actual django form fields. An example containing a complete &lt;span class="caps"&gt;JSON&lt;/span&gt; described form
is the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
[
    {
        &amp;quot;name&amp;quot;: &amp;quot;firstname&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;First Name&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;text&amp;quot;,
        &amp;quot;max_length&amp;quot;: 25,
        &amp;quot;required&amp;quot;: 1
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;lastname&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Last Name&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;text&amp;quot;,
        &amp;quot;max_length&amp;quot;: 25,
        &amp;quot;required&amp;quot;: 1
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;smallcv&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Small CV&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;textarea&amp;quot;,
        &amp;quot;help_text&amp;quot;: &amp;quot;Please insert a small CV&amp;quot;
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;age&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Age&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;integer&amp;quot;,
        &amp;quot;max_value&amp;quot;: 200,
        &amp;quot;min_value&amp;quot;: 0
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;marital_status&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Marital Status&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;radio&amp;quot;,
        &amp;quot;choices&amp;quot;: [
            {&amp;quot;name&amp;quot;: &amp;quot;Single&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;single&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Married&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;married&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Divorced&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;divorced&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Widower&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;widower&amp;quot;}
        ]
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;occupation&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Occupation&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;select&amp;quot;,
        &amp;quot;choices&amp;quot;: [
            {&amp;quot;name&amp;quot;: &amp;quot;Farmer&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;farmer&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Engineer&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;engineer&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Teacher&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;teacher&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Office Clerk&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;office_clerk&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Merchant&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;merchant&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Unemployed&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;unemployed&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Retired&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;retired&amp;quot;},
            {&amp;quot;name&amp;quot;: &amp;quot;Other&amp;quot;, &amp;quot;value&amp;quot;:&amp;quot;other&amp;quot;}
        ]
    },
    {
        &amp;quot;name&amp;quot;: &amp;quot;internet&amp;quot;,
        &amp;quot;label&amp;quot;: &amp;quot;Internet Access&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;checkbox&amp;quot;
    }
]
&lt;/pre&gt;
&lt;p&gt;The above &lt;span class="caps"&gt;JSON&lt;/span&gt; string can be easily converted to an array of dictionaries with the following&amp;nbsp;code:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import json
fields=json.loads(json_fields)
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-the-form-fields"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Creating the form&amp;nbsp;fields&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most import part in the django dynamic form creation is to convert the above array
of field-describing dictionaries to actual objects of type &lt;tt class="docutils literal"&gt;django.forms.Field&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;To help with that I implemented a class named &lt;tt class="docutils literal"&gt;FieldHandler&lt;/tt&gt; which gets an
array of field dictionaries and after initialization will have an attribute named &lt;tt class="docutils literal"&gt;formfields&lt;/tt&gt; which
will be a dictionary with keys the names of each field an values the corresponding &lt;tt class="docutils literal"&gt;django.forms.Field&lt;/tt&gt; objects. The implementation is as&amp;nbsp;follows:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import django.forms

class FieldHandler():
    formfields = {}
    def __init__(self, fields):
        for field in fields:
            options = self.get_options(field)
            f = getattr(self, &amp;quot;create_field_for_&amp;quot;+field['type'] )(field, options)
            self.formfields[field['name']] = f

    def get_options(self, field):
        options = {}
        options['label'] = field['label']
        options['help_text'] = field.get(&amp;quot;help_text&amp;quot;, None)
        options['required'] = bool(field.get(&amp;quot;required&amp;quot;, 0) )
        return options

    def create_field_for_text(self, field, options):
        options['max_length'] = int(field.get(&amp;quot;max_length&amp;quot;, &amp;quot;20&amp;quot;) )
        return django.forms.CharField(**options)

    def create_field_for_textarea(self, field, options):
        options['max_length'] = int(field.get(&amp;quot;max_value&amp;quot;, &amp;quot;9999&amp;quot;) )
        return django.forms.CharField(widget=django.forms.Textarea, **options)

    def create_field_for_integer(self, field, options):
        options['max_value'] = int(field.get(&amp;quot;max_value&amp;quot;, &amp;quot;999999999&amp;quot;) )
        options['min_value'] = int(field.get(&amp;quot;min_value&amp;quot;, &amp;quot;-999999999&amp;quot;) )
        return django.forms.IntegerField(**options)

    def create_field_for_radio(self, field, options):
        options['choices'] = [ (c['value'], c['name'] ) for c in field['choices'] ]
        return django.forms.ChoiceField(widget=django.forms.RadioSelect,   **options)

    def create_field_for_select(self, field, options):
        options['choices']  = [ (c['value'], c['name'] ) for c in field['choices'] ]
        return django.forms.ChoiceField(  **options)

    def create_field_for_checkbox(self, field, options):
        return django.forms.BooleanField(widget=django.forms.CheckboxInput, **options)
&lt;/pre&gt;
&lt;p&gt;As can be seen, in the &lt;tt class="docutils literal"&gt;__init__&lt;/tt&gt; method, the &lt;tt class="docutils literal"&gt;get_options&lt;/tt&gt; method is called first which
returns a dictionary with the common options (label, help_text, required). After that,
depending on the type of each field the correct method will be generated with
&lt;tt class="docutils literal"&gt;getattr(self, &lt;span class="pre"&gt;&amp;quot;create_field_for_&amp;quot;+field['type']&lt;/span&gt; )&lt;/tt&gt; (so if type is text this
will return a reference to the create_field_for_text method) and then called passing
the field dictinary and the options returned from &lt;tt class="docutils literal"&gt;get_options&lt;/tt&gt;. Each one of
the &lt;tt class="docutils literal"&gt;create_field_for_xxx&lt;/tt&gt; methods will extract the required (or optional)
attributes for the specific field type, update options and initialize the correct Field passing
the options as kwargs. Finally the formfields attribute will be updated with the name
and Field&amp;nbsp;object.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-the-actual-form"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Creating the actual&amp;nbsp;form&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create the actual dynamic &lt;tt class="docutils literal"&gt;django.forms.Form&lt;/tt&gt; I used the function &lt;tt class="docutils literal"&gt;get_form&lt;/tt&gt;
which receives a string with the json description, parses it to a python array,
creates the array of fields with the help of &lt;tt class="docutils literal"&gt;FieldHandler&lt;/tt&gt; and then generates
the &lt;tt class="docutils literal"&gt;Form&lt;/tt&gt; class with &lt;tt class="docutils literal"&gt;type&lt;/tt&gt; passing it &lt;tt class="docutils literal"&gt;django.forms.Form&lt;/tt&gt; as a parent
and the array of &lt;tt class="docutils literal"&gt;django.forms.Field&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;FieldHandler&lt;/tt&gt; as&amp;nbsp;attributes:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
def get_form(jstr):
    fields=json.loads(jstr)
    fh = FieldHandler(fields)
    return type('DynaForm', (django.forms.Form,), fh.formfields )
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="using-the-dynamic-form"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Using the dynamic&amp;nbsp;form&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The result of &lt;tt class="docutils literal"&gt;get_form&lt;/tt&gt; can be used as a normal form class. As an&amp;nbsp;example:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
import dynaform

def dform(request):
    json_form = get_json_form_from_somewhere()
    form_class = dynaform.get_form(json_form)
    data = {}
    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            data = form.cleaned_data
    else:
        form = form_class()

    return render_to_response( &amp;quot;dform.html&amp;quot;, {
        'form': form,  'data': data,
    }, RequestContext(request) )
&lt;/pre&gt;
&lt;p&gt;So, we have to get our &lt;span class="caps"&gt;JSON&lt;/span&gt; form description from somewhere (for instance
a field in a model) and then generate the form class with &lt;tt class="docutils literal"&gt;get_form&lt;/tt&gt;.
After that we follow the normal procedure of checking if the &lt;tt class="docutils literal"&gt;request.method&lt;/tt&gt;
is &lt;span class="caps"&gt;POST&lt;/span&gt; so we pass the &lt;span class="caps"&gt;POST&lt;/span&gt; data to the form and check if it is value or
we just create an empty form. As a result we just pass the data that was
read from the form to the view for&amp;nbsp;presentation.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 24 Dec 2013 14:20:00 +0200</pubDate><guid>tag:spapas.github.io,2013-12-24:2013/12/24/django-dynamic-forms/</guid><category>django</category><category>python</category><category>forms</category></item><item><title>Django authority data</title><link>http://spapas.github.io/2013/11/05/django-authoritiy-data/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#defining-authorities" id="id2"&gt;Defining authorities&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-groups" id="id3"&gt;Using&amp;nbsp;groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#by-storing-the-authority-to-the-session" id="id4"&gt;By storing the authority to the&amp;nbsp;session&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#by-using-a-custom-user-profile" id="id5"&gt;By using a Custom User&amp;nbsp;Profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#getting-the-authority-of-the-user-has-to-be-dry" id="id6"&gt;Getting the authority of the user has to be &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#adding-authority-data" id="id7"&gt;Adding authority&amp;nbsp;data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id8"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One common requirement in an organization is to separate users in authorities (meaning departments / units / branches etc)
and each authority have its own data. So users belonging to the &amp;quot;Athens Branch&amp;quot; won&amp;#8217;t be able to
edit data submitted from users of the &amp;quot;Thessaloniki&amp;nbsp;Branch&amp;quot;.&lt;/p&gt;
&lt;p&gt;This is a special case of the more general row-level-security in which each instance of a domain object will
have an &lt;span class="caps"&gt;ACL&lt;/span&gt;. Row-level-security would need a many-to-many relation between object instances and authorities, something
that would be overkill in our&amp;nbsp;case.&lt;/p&gt;
&lt;p&gt;Authority data is also a more general case of the user-data meaning that each user can have access
to data that he inserts in the system. Implementing user-data is easy using the techniques we will present&amp;nbsp;below.&lt;/p&gt;
&lt;p&gt;We have to notice that the django permissions do not support our requirements since they define security for all instances of a&amp;nbsp;model.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="defining-authorities"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Defining&amp;nbsp;authorities&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to have custom authorities I propose first of all to add an Authority model that would define the authority. Even if
your authorities only have a name I believe that adding the Authority model would be beneficial.
Now, there are many ways to separate normal django users (&lt;tt class="docutils literal"&gt;django.contrib.auth.models.User&lt;/tt&gt;) to&amp;nbsp;authorities:&lt;/p&gt;
&lt;div class="section" id="using-groups"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id3"&gt;Using&amp;nbsp;groups&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Just define a &lt;tt class="docutils literal"&gt;django.contrib.auth.models.Group&lt;/tt&gt; for each authority and add the users to the groups you want using the django-admin.
Your Authority model would have an one-to-one relation with the &lt;tt class="docutils literal"&gt;django.contrib.auth.models.Group&lt;/tt&gt; so you will be able to find out the other
information of the authority (since django groups only have&amp;nbsp;names).&lt;/p&gt;
&lt;p&gt;Now you can just get the groups for the user and find out his authorities. This could lead to problems when users belong to django groups
that are not related to authorities so you must filter these out (for instance by checking which groups actually have a corresponding&amp;nbsp;Authority).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="by-storing-the-authority-to-the-session"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id4"&gt;By storing the authority to the&amp;nbsp;session&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When the user logs in you can add an attribute to the session that would save the authority of the user. To do that, you should define
a custom middleware that checks to see if there is an authority attribute to the session and if not it will do whatever it needs to find it and set it.
An example is&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class CustomAuthorityMiddleware:
  def process_request(self, request):
    if not request.session.get('authority'):
      authority = get_the_authority(request.user)
      request.session['authority']=authority
&lt;/pre&gt;
&lt;p&gt;This way, whenever you want to find out the authority of the user you just check the&amp;nbsp;session.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="by-using-a-custom-user-profile"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5"&gt;By using a Custom User&amp;nbsp;Profile&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Just create a &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model"&gt;django user profile&lt;/a&gt; and add to it a &lt;tt class="docutils literal"&gt;ForeignKey&lt;/tt&gt; to your Authority&amp;nbsp;model:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class Profile(models.Model):
  user = models.OneToOneField('django.auth.User')
  authority = models.ForeignKey('authorities.Authority', blank=True, null=True )

class Authority(models.Model):
  id = models.IntegerField(primary_key = True)
  name = models.CharField(max_length=64, )
  auth_type = models.CharField(max_length=16, )
&lt;/pre&gt;
&lt;p&gt;You can get the authority of the user through &lt;tt class="docutils literal"&gt;request.user.profile.authority&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="getting-the-authority-of-the-user-has-to-be-dry"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;Getting the authority of the user has to be &lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Whatever method you use to define the authorities of your users you have to remember that it is very
important to define somewhere a function that will return the authority (or authorities) of a
user. You need to define a function even in the simple case in which your function would just return &lt;tt class="docutils literal"&gt;request.user.profile.authority&lt;/tt&gt;.
This will greatly help you when you wish to add some logic to this, for instance &amp;quot;quickly disable users belonging to Authority X
or temporary move users from Authority Y to authority&amp;nbsp;Z&amp;quot;.&lt;/p&gt;
&lt;p&gt;Let us suppose that you have defined a &lt;tt class="docutils literal"&gt;get_user_authority&lt;/tt&gt; function. Also, you need to define a &lt;tt class="docutils literal"&gt;has_access&lt;/tt&gt; function
that would decide if a users/request has access to a particular object. This also needs to be &lt;span class="caps"&gt;DRY&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-authority-data"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7"&gt;Adding authority&amp;nbsp;data&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To define authority data you have to add a field to your model that would define its authority, for instance like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuthorityData(models.Model):
  authority = models.ForeignKey('authorities.Authority', editable=False,)
&lt;/pre&gt;
&lt;p&gt;This field should not be editable (at least by your end users) because they shouldn&amp;#8217;t be able to change the authority of the data they&amp;nbsp;insert.&lt;/p&gt;
&lt;p&gt;If you want to have user-data then just add a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;models.ForeignKey('django.auth.User',&lt;/span&gt; editable=False)&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Now, your Create and Update Class Based Views have to pass the request to your forms and also your Detail and Update &lt;span class="caps"&gt;CBV&lt;/span&gt; should allow only getting
objects that belong to the authority of the&amp;nbsp;user:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuthorityDataCreateView(CreateView):
  model=models.AuthorityData

  def get_form_kwargs(self):
      kwargs = super(AuthorityDataCreateView, self).get_form_kwargs()
      kwargs.update({'request': self.request})
      return kwargs

class AuthorityDataDetailView(DetailView):
  def get_object(self, queryset=None):
      obj = super(AuthorityDataDetailView, self).get_object(queryset)
      if if not user_has_access(obj, self.request):
          raise Http404(u&amp;quot;Access Denied&amp;quot;)
      return obj

class AuthorityDataUpdateView(UpdateView):
  model=models.AuthorityData

  def get_form_kwargs(self):
      kwargs = super(AuthorityDataUpdateView, self).get_form_kwargs()
      kwargs.update({'request': self.request})
      return kwargs

  def get_object(self, queryset=None):
      obj = super(AuthorityDataUpdateView, self).get_object(queryset)
      if if not user_has_access(obj, self.request):
          raise Http404(u&amp;quot;Access Denied&amp;quot;)
      return obj
&lt;/pre&gt;
&lt;p&gt;Your ModelForm can now use the request to get the Authority and set it (don&amp;#8217;t forget
that you should not use &lt;tt class="docutils literal"&gt;Meta.exclude&lt;/tt&gt; but instead use &lt;tt class="docutils literal"&gt;Meta.include&lt;/tt&gt;!):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuthorityDataModelForm(forms.ModelForm):
    class Meta:
      model = models.AuthorityData
      exclude = ('authority',)

    def __init__(self, *args, **kwargs):
      self.request = kwargs.pop('request', None)
      super(ActionModelForm, self).__init__(*args, **kwargs)


    def save(self, force_insert=False, force_update=False, commit=True):
      obj = super(AuthorityDataModelForm, self).save(commit=False)
      if obj:
          obj.authority = get_user_authority(self.request)
          obj.save()
      return obj
&lt;/pre&gt;
&lt;p&gt;The previous work fine for Create/Detail/Update CBVs but not for ListsViews. List views querysets
and in general all queries to the object have to be filtered through&amp;nbsp;authority.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
class AuthorityDataListView(ListView):
  def get_queryset(self):
    queryset = super(AuthorityDataModelForm, self).get_queryset()
    return queryset.filter(authority = get_user_authority(request))
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id8"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the above techniques we can define authority (or just user) data. Your AuthorityData should
have a &lt;tt class="docutils literal"&gt;ForeignKey&lt;/tt&gt; to your Authority  and you have configure your queries, ModelForms and CBVs
to use that. If you have more than one models that belong to an authority and want to stay &lt;span class="caps"&gt;DRY&lt;/span&gt; then you&amp;#8217;d need
to define all the above as &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/"&gt;mixins&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 05 Nov 2013 14:20:00 +0200</pubDate><guid>tag:spapas.github.io,2013-11-05:2013/11/05/django-authoritiy-data/</guid><category>django</category><category>python</category><category>security</category></item><item><title>Using custom authorities with spring-security LDAP authentication</title><link>http://spapas.github.io/2013/10/14/spring-ldap-custom-authorities/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id3"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#a-basic-spring-security-setup" id="id4"&gt;A basic spring security&amp;nbsp;setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#spring-security-ldap-with-custom-authorities" id="id5"&gt;Spring security &lt;span class="caps"&gt;LDAP&lt;/span&gt; with custom authorities&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#contextsource" id="id6"&gt;contextSource&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#usersearch" id="id7"&gt;userSearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#ldapauthprovider" id="id8"&gt;ldapAuthProvider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#customldapauthoritiespopulator" id="id9"&gt;CustomLdapAuthoritiesPopulator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#example" id="id10"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#conclusion" id="id11"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One very useful component of the &lt;a class="reference external" href="http://spring.io/"&gt;spring&lt;/a&gt; java framework is &lt;a class="reference external" href="http://projects.spring.io/spring-security/"&gt;spring-security&lt;/a&gt; since it allows consistent usage of various security providers for
authentication and authorization. Although I&amp;#8217;ve found a great number of basic spring-security tutorials on the internet, I wasn&amp;#8217;t able to find a complete solution for my own&amp;nbsp;requirements:&lt;/p&gt;
&lt;p&gt;Logging in with &lt;span class="caps"&gt;LDAP&lt;/span&gt; but configuring the authorities &lt;a class="footnote-reference" href="#id2" id="id1"&gt;[*]&lt;/a&gt; of the logged in user with the help of a custom method and not through &lt;span class="caps"&gt;LDAP&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I think that the above is a common requirement in many organizations: There is a central &lt;span class="caps"&gt;LDAP&lt;/span&gt; repository in which the usernames and passwords of the users are stored, but the groups of the users are not stored there. Or maybe the groups that are actually stored in the &lt;span class="caps"&gt;LDAP&lt;/span&gt; cannot be transformed easily to application specific groups for each&amp;nbsp;application.&lt;/p&gt;
&lt;p&gt;You may find the working spring project that uses ldap and a custom groups populator here: &lt;a class="reference external" href="https://github.com/spapas/SpringLdapCustomAuthorities/"&gt;https://github.com/spapas/SpringLdapCustomAuthorities/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-basic-spring-security-setup"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;A basic spring security&amp;nbsp;setup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve created a very basic setup for spring-security for a spring-mvc project. Please take a look here for a more thorough explanation of a simple spring-security project &lt;a class="reference external" href="http://www.mkyong.com/spring-security/spring-security-hello-world-example/"&gt;http://www.mkyong.com/spring-security/spring-security-hello-world-example/&lt;/a&gt; and here &lt;a class="reference external" href="http://www.codeproject.com/Articles/253901/Getting-Started-Spring-Security"&gt;http://www.codeproject.com/Articles/253901/Getting-Started-Spring-Security&lt;/a&gt; for a great explanation of the various spring-security&amp;nbsp;classes.&lt;/p&gt;
&lt;p&gt;In my setup there is a controller that defines two mappings, the &amp;quot;/&amp;quot; which is the homepage that has a link to the &amp;quot;/enter&amp;quot; and the &amp;quot;/enter&amp;quot; which is an internal page in which only authorized users have access. When the user clicks on &amp;quot;enter&amp;quot; he will be represented with a login form first. If the use logs in successfully, the enter.jsp will list the username and the authorities of the logged in user through the following spring-security&amp;nbsp;tags:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;&amp;lt;%@&lt;/span&gt; &lt;span class="n"&gt;taglib&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;sec&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/security/tags&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;%&amp;gt;&lt;/span&gt;
[...]
Username: &lt;span class="nt"&gt;&amp;lt;sec:authentication&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;principal.username&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
Authorities: &lt;span class="nt"&gt;&amp;lt;sec:authentication&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;principal.authorities&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The authentication provider is an in memory service in which the username, password and authorities of each user are defined in the &lt;span class="caps"&gt;XML&lt;/span&gt;. So this is a simple spring-security example that can be found in a number of places on the internet. The security rules, login form and the authentication provider are configured with the following &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;security-config.xml&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;beans:beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/security&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:beans=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/beans&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/security&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/security/spring-security-3.1.xsd&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;http&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/static/**&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;security=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;none&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;http&lt;/span&gt; &lt;span class="na"&gt;use-expressions=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;permitAll&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/enter&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hasRole(&amp;#39;user&amp;#39;)&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/**&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;denyAll&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;form-login&lt;/span&gt; &lt;span class="na"&gt;default-target-url=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;logout&lt;/span&gt;  &lt;span class="na"&gt;logout-success-url=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/http&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;authentication-provider&amp;gt;&lt;/span&gt;
           &lt;span class="nt"&gt;&amp;lt;user-service&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;user&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;spapas&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;123&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;authorities=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;admin, user, nonldap&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;user&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;serafeim&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;password=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;123&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;authorities=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;user&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
           &lt;span class="nt"&gt;&amp;lt;/user-service&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;/authentication-provider&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/authentication-manager&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/beans:beans&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we run this application and go to the /enter, we will get the following&amp;nbsp;output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Username:&amp;nbsp;spapas&lt;/p&gt;
&lt;p&gt;Authorities: [admin, nonldap,&amp;nbsp;user]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="spring-security-ldap-with-custom-authorities"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id5"&gt;Spring security &lt;span class="caps"&gt;LDAP&lt;/span&gt; with custom&amp;nbsp;authorities&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The previous application can be modified to login through &lt;span class="caps"&gt;LDAP&lt;/span&gt; and get the authorities from a custom class. The main differences are in the &lt;tt class="docutils literal"&gt;pom.xml&lt;/tt&gt; which adsd the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;spring-security-ldap&lt;/span&gt;&lt;/tt&gt; dependency, the addition of a &lt;tt class="docutils literal"&gt;CustomLdapAuthoritiesPopulator.java&lt;/tt&gt; which does the actual mapping of username to authority and various changes to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;security-config.xml&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;As you will see we had to define our security beans mainly using spring beans and not using the various elements from security namespace like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;ldap-server&amp;gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;ldap-authentication-provder&amp;gt;&lt;/span&gt;&lt;/tt&gt;. For a good tutorial on using these elements and ldap in spring security in general check these out: &lt;a class="reference external" href="http://docs.spring.io/spring-security/site/docs/3.1.x/reference/ldap.html"&gt;http://docs.spring.io/spring-security/site/docs/3.1.x/reference/ldap.html&lt;/a&gt; and &lt;a class="reference external" href="http://krams915.blogspot.gr/2011/01/spring-security-mvc-using-ldap.html"&gt;http://krams915.blogspot.gr/2011/01/spring-security-mvc-using-ldap.html&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;beans:beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/security&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:beans=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.springframework.org/schema/beans&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/security&lt;/span&gt;
&lt;span class="s"&gt;                   http://www.springframework.org/schema/security/spring-security-3.1.xsd&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;http&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/static/**&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;security=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;none&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;http&lt;/span&gt; &lt;span class="na"&gt;use-expressions=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;permitAll&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/enter&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hasRole(&amp;#39;user&amp;#39;)&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;intercept-url&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/**&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;access=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;denyAll&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;form-login&lt;/span&gt; &lt;span class="na"&gt;default-target-url=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;logout&lt;/span&gt;  &lt;span class="na"&gt;logout-success-url=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/http&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;contextSource&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.springframework.security.ldap.DefaultSpringSecurityContextSource&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ldap://login.serafeim.gr:389/dc=serafeim,dc=gr&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;anonymousReadOnly&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;userSearch&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.springframework.security.ldap.search.FilterBasedLdapUserSearch&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&lt;/span&gt; &lt;span class="na"&gt;index=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&lt;/span&gt; &lt;span class="na"&gt;index=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;(uid={0})&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&lt;/span&gt; &lt;span class="na"&gt;index=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;contextSource&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ldapAuthProvider&amp;quot;&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.springframework.security.ldap.authentication.LdapAuthenticationProvider&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.springframework.security.ldap.authentication.BindAuthenticator&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;contextSource&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;userSearch&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;userSearch&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt;
&lt;span class="c"&gt;         &amp;lt;beans:property name=&amp;quot;userDnPatterns&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;           &amp;lt;beans:list&amp;gt;&amp;lt;beans:value&amp;gt;uid={0},ou=People&amp;lt;/beans:value&amp;gt;&amp;lt;/beans:list&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;         &amp;lt;/beans:property&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;         --&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/beans:constructor-arg&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;beans:constructor-arg&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;gr.serafeim.springldapcustom.CustomLdapAuthoritiesPopulator&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/beans:constructor-arg&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;authentication-provider&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ldapAuthProvider&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/authentication-manager&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/beans:beans&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, in the above configuration we&amp;#8217;ve defined three spring beans: &lt;tt class="docutils literal"&gt;contextSource&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;userSearch&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;ldapAuthProvider&lt;/tt&gt;. The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;&lt;/tt&gt; element uses the &lt;tt class="docutils literal"&gt;ldapAuthProvider&lt;/tt&gt; as an authentication provider. Below we will explain these&amp;nbsp;beans:&lt;/p&gt;
&lt;div class="section" id="contextsource"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;contextSource&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The contextSource bean defines the actual &lt;span class="caps"&gt;LDAP&lt;/span&gt; server that we are going to connect to. It has the class &lt;tt class="docutils literal"&gt;o.s.s.ldap.DefaultSpringSecurityContextSource&lt;/tt&gt;. This will need to be passed to other beans that would need to connect to the server for a number of operations. We pass to it the url of our &lt;span class="caps"&gt;LDAP&lt;/span&gt; server and set its &lt;tt class="docutils literal"&gt;anonymousReadOnly&lt;/tt&gt; property to true. The &lt;tt class="docutils literal"&gt;anonymousReadOnly&lt;/tt&gt; defines if we can anonymously connect to our &lt;span class="caps"&gt;LDAP&lt;/span&gt; server in order to perform the search operation below. If we cannot connect anonymously then we have to set its &lt;tt class="docutils literal"&gt;userDn&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;password&lt;/tt&gt; properties.&lt;/p&gt;
&lt;p&gt;A very interesting question is if the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;ldap-server&amp;gt;&lt;/span&gt;&lt;/tt&gt; element of the spring security namespace is related to &lt;tt class="docutils literal"&gt;the o.s.s.ldap.DefaultSpringSecurityContextSource&lt;/tt&gt; like our &lt;tt class="docutils literal"&gt;contextSource&lt;/tt&gt;. To find out, we need to check the &lt;tt class="docutils literal"&gt;o.s.s.config.SecurityNamespaceHandler&lt;/tt&gt; class of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;spring-security-config.jar&lt;/span&gt;&lt;/tt&gt;. In there we see the &lt;tt class="docutils literal"&gt;loadParsers&lt;/tt&gt; method which has the line: &lt;tt class="docutils literal"&gt;parsers.put(Elements.LDAP_SERVER, new &lt;span class="pre"&gt;LdapServerBeanDefinitionParser());&lt;/span&gt;&lt;/tt&gt;. The constant &lt;tt class="docutils literal"&gt;o.s.s.config.Elements.LDAP_SERVER&lt;/tt&gt; has the value of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;ldap-server&amp;quot;&lt;/span&gt;&lt;/tt&gt; as expected, so we need to see what does the class &lt;tt class="docutils literal"&gt;o.s.s.config.ldap.LdapServerBeanDefinitionParser&lt;/tt&gt; do. This class has a parse() method that receives the xml that was used to instantiate the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;ldap-server&amp;gt;&lt;/span&gt;&lt;/tt&gt; element and, depending an on the actualy configuration, instantiates a bean of the class &lt;tt class="docutils literal"&gt;o.s.s.ldap.DefaultSpringSecurityContextSource&lt;/tt&gt; with an id of &lt;tt class="docutils literal"&gt;o.s.s.securityContextSource&lt;/tt&gt; that will be used by the other elements in the security namespace&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;This actually solves another question I had concerning the following&amp;nbsp;error:&lt;/p&gt;
&lt;blockquote&gt;
No bean named &amp;#8216;org.springframework.security.authenticationManager&amp;#8217; is defined: Did you forget to add a gobal &amp;lt;authentication-manager&amp;gt; element to your configuration (with child &amp;lt;authentication-provider&amp;gt;  elements)? Alternatively you can use the authentication-manager-ref attribute on your &amp;lt;http&amp;gt; and &amp;lt;global-method-security&amp;gt; elements.&lt;/blockquote&gt;
&lt;p&gt;What happens is that when spring-security-configuration encounters an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;&lt;/tt&gt; it will instantiate a bean named &lt;tt class="docutils literal"&gt;o.s.s.authenticationManager&lt;/tt&gt;  having the class
&lt;tt class="docutils literal"&gt;o.s.s.authentication.ProviderManager&lt;/tt&gt; and will create and pass to it a &lt;tt class="docutils literal"&gt;providers&lt;/tt&gt; list with all the authentication providers that are defined inside the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;&lt;/tt&gt; element with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;authentication-provider&amp;gt;&lt;/span&gt;&lt;/tt&gt; nodes. So, if you encounter the above error, the problem is that for some reason your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;authentication-manager&amp;gt;&lt;/span&gt;&lt;/tt&gt; is not configured correctly, so no &lt;tt class="docutils literal"&gt;o.s.s.authenticatioManager&lt;/tt&gt; bean is&amp;nbsp;created!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="usersearch"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;userSearch&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;userSearch&lt;/tt&gt; bean is needed if we don&amp;#8217;t know exactly where our users are stored in the &lt;span class="caps"&gt;LDAP&lt;/span&gt; directory so we will use this bean as a search filter. If we do know our user tree then we won&amp;#8217;t need this bean at all as will be explained later. It has the class &lt;tt class="docutils literal"&gt;o.s.s.ldap.search.FilterBasedLdapUserSearch&lt;/tt&gt; and gets three constructor parameters: &lt;tt class="docutils literal"&gt;searchBase&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;searchFilter&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;contextSource&lt;/tt&gt;. The &lt;tt class="docutils literal"&gt;searchBase&lt;/tt&gt; is from where in the &lt;span class="caps"&gt;LDAP&lt;/span&gt; tree to start searching (empty in our case), the &lt;tt class="docutils literal"&gt;searchFilter&lt;/tt&gt; defines where is the username (uid in our case) and the &lt;tt class="docutils literal"&gt;contextSource&lt;/tt&gt; has been defined&amp;nbsp;before.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ldapauthprovider"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8"&gt;ldapAuthProvider&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is the actual &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;authentication-provider&lt;/span&gt;&lt;/tt&gt; that the spring-security &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;authentication-manager&lt;/span&gt;&lt;/tt&gt; is going to use. It is an instance of class &lt;tt class="docutils literal"&gt;o.s.s.ldap.authentication.LdapAuthenticationProvider&lt;/tt&gt; which has two main properties: An &lt;tt class="docutils literal"&gt;o.s.s.ldap.authentication.LdapAuthenticator&lt;/tt&gt; implementation and an &lt;tt class="docutils literal"&gt;o.s.s.ldap.userdetails.LdapAuthoritiesPopulator&lt;/tt&gt; implementation. The first interface defines an &lt;tt class="docutils literal"&gt;authenticate&lt;/tt&gt; method and is used to actually authenticate the user with the &lt;span class="caps"&gt;LDAP&lt;/span&gt; server. The second interface defines a &lt;tt class="docutils literal"&gt;getGrantedAuthorities&lt;/tt&gt; which returns the roles for the authenticated user. The LdapAuthoritiesPopulator parameter is actually optional (so we can use &lt;span class="caps"&gt;LDAP&lt;/span&gt; to authenticate only the users) and we can provide our own implementation to have custom authorities for our application. That is exactly what we&amp;#8217;ve done&amp;nbsp;here.&lt;/p&gt;
&lt;p&gt;The two arguments used to initialize the ldapAuthProvoder are one instance of &lt;tt class="docutils literal"&gt;o.s.s.ldap.authentication.BindAuthenticator&lt;/tt&gt; which is a simple authenticator that tries to bind with the given credentials to the &lt;span class="caps"&gt;LDAP&lt;/span&gt; server to check the credentials and one instance of a custom class named &lt;tt class="docutils literal"&gt;g.s.s.CustomLdapAuthoritiesPopulator&lt;/tt&gt; which is the actual implementation of the custom roles provider. The &lt;tt class="docutils literal"&gt;BindAuthenticator&lt;/tt&gt; gets the &lt;tt class="docutils literal"&gt;contextSource&lt;/tt&gt; as a constructor parameter and its &lt;tt class="docutils literal"&gt;userSearch&lt;/tt&gt; property is set with the &lt;tt class="docutils literal"&gt;userSearch&lt;/tt&gt; bean defined previously. If we instead knew the actual place of the users, we could use the commented out &lt;tt class="docutils literal"&gt;userDnPatterns&lt;/tt&gt; property which takes a list of possible places in the &lt;span class="caps"&gt;LDAP&lt;/span&gt; catalog which will be checked for the&amp;nbsp;username.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="customldapauthoritiespopulator"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9"&gt;CustomLdapAuthoritiesPopulator&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;CustomLdapAuthoritiesPopulator&lt;/tt&gt; just needs to implement the &lt;tt class="docutils literal"&gt;LdapAuthoritiesPopulator&lt;/tt&gt; interface. Here&amp;#8217;s our&amp;nbsp;implmentation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="n"&gt;gr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serafeim&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springldapcustom&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Collection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashSet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.ldap.core.DirContextOperations&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.security.core.GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.security.core.authority.SimpleGrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomLdapAuthoritiesPopulator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;LdapAuthoritiesPopulator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="nd"&gt;@Override&lt;/span&gt;
       &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getGrantedAuthorities&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                       &lt;span class="n"&gt;DirContextOperations&lt;/span&gt; &lt;span class="n"&gt;userData&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;gas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
               &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;spapas&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                       &lt;span class="n"&gt;gas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SimpleGrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;admin&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
               &lt;span class="o"&gt;}&lt;/span&gt;
               &lt;span class="n"&gt;gas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SimpleGrantedAuthority&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;user&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
               &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;gas&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
       &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;getGrantedAuthorities&lt;/tt&gt; just checks the username and add another role if it is a specific one. Of course here we would autowire our user roles repository and query the database to get the roles of the user, however I&amp;#8217;m not going to do that for the case of&amp;nbsp;simplicity.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="example"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10"&gt;Example&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When we run this application and go to the /enter, after logging in with our &lt;span class="caps"&gt;LDAP&lt;/span&gt; credentials as spapas, we will get the following&amp;nbsp;output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Username:&amp;nbsp;spapas&lt;/p&gt;
&lt;p&gt;Authorities: [admin,&amp;nbsp;user]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id11"&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the previous a complete example of configuring a custom authorities populator was represented. Using this configuration we can login through the &lt;span class="caps"&gt;LDAP&lt;/span&gt; server of our organization but use application specific roles for our logged-in&amp;nbsp;users.&lt;/p&gt;
&lt;!-- font-size: 0.5em;
vertical-align: top; --&gt;
&lt;table class="docutils footnote" frame="void" id="id2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[*]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Which is how spring calls the groups/roles the user belongs to&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 14 Oct 2013 08:55:00 +0300</pubDate><guid>tag:spapas.github.io,2013-10-14:2013/10/14/spring-ldap-custom-authorities/</guid><category>spring</category><category>spring-security</category><category>java</category><category>ldap</category><category>authentication</category></item><item><title>git branches</title><link>http://spapas.github.io/2013/10/08/git-branches/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-a-new-git-repository" id="id2"&gt;Creating a new git&amp;nbsp;repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#branching" id="id3"&gt;Branching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#remote-branches" id="id4"&gt;Remote&amp;nbsp;branches&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;a class="reference external" href="http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is"&gt;branch&lt;/a&gt; is a very interesting git feature. With this you may have more than one &lt;em&gt;branches&lt;/em&gt; in the same repository. The main
usage of this feature would be to create different versions of your source code to parallel test development of different features.
When the development of each of these features has been finished then the different versions would need to be combined (or merged) to a
single version. Of course, merging is not always the result of branching - some branches may exist indefinitely or other may just  be
deleted without&amp;nbsp;merging.&lt;/p&gt;
&lt;p&gt;I will try to experiment with it and comment on the&amp;nbsp;results.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-a-new-git-repository"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Creating a new git&amp;nbsp;repository&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s start by creating a new git&amp;nbsp;repository:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\&amp;gt;mkdir testgit
D:\&amp;gt;cd testgit
D:\testgit&amp;gt;echo contents 11 &amp;gt; file1.txt
D:\testgit&amp;gt;echo contents 222 &amp;gt; file2.txt
D:\testgit&amp;gt;echo 3333 &amp;gt; file2.txt
D:\testgit&amp;gt;copy con file3.txt
line 1 of file 3

line 3 of file 3

test

line 7 of file 3
^Z
       1 files copied.

D:\testgit&amp;gt;git init
Initialized empty Git repository in D:/testgit/.git/
D:\testgit&amp;gt;git add .
D:\testgit&amp;gt;git commit -m Initial
[master (root-commit) 96ca9af] Initial
 3 files changed, 9 insertions(+)
 create mode 100644 file1.txt
 create mode 100644 file2.txt
 create mode 100644 file3.txt
&lt;/pre&gt;
&lt;p&gt;To see the branch we are in we can use the &lt;tt class="docutils literal"&gt;git branch&lt;/tt&gt; command. Also &lt;tt class="docutils literal"&gt;git status&lt;/tt&gt; outputs the current&amp;nbsp;branch:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git status
# On branch master
nothing to commit, working directory clean
D:\testgit&amp;gt;git branch
* master
&lt;/pre&gt;
&lt;p&gt;So, it seems that when we create a new repository, a &amp;quot;master&amp;quot; branch is&amp;nbsp;created.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="branching"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Branching&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lets create a new branch and change our working branch to&amp;nbsp;it:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git branch slave
D:\testgit&amp;gt;git branch
* master
  slave
D:\testgit&amp;gt;git checkout slave
Switched to branch 'slave'
D:\testgit&amp;gt;git branch
  master
* slave
&lt;/pre&gt;
&lt;p&gt;We can see that now the slave branch is the current one. Let&amp;#8217;s do some changes and add commit them to the slave&amp;nbsp;branch:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git branch
  master
* slave
D:\testgit&amp;gt;echo new file1 contents &amp;gt; file1.txt
D:\testgit&amp;gt;git commit -m &amp;quot;Slave modification&amp;quot;
[slave b6083ad] Slave modification
 1 file changed, 1 insertion(+), 1 deletion(-)
D:\testgit&amp;gt;git checkout master
Switched to branch 'master'
D:\testgit&amp;gt;more file1.txt
contents 11
D:\testgit&amp;gt;git checkout slave
Switched to branch 'slave'
D:\testgit&amp;gt;more file1.txt
new file1 contents
&lt;/pre&gt;
&lt;p&gt;So the contents of file1.txt in the branch master is &lt;tt class="docutils literal"&gt;contents 11&lt;/tt&gt; while the contents of the same file
in the branch slave is &lt;tt class="docutils literal"&gt;new file1 contents&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;An interested behaviour is what happens with uncommit changes when changing branches. Let&amp;#8217;s try deleting a&amp;nbsp;file:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;del file2.txt
D:\testgit&amp;gt;git status
# On branch master
# Changes not staged for commit:
#   (use &amp;quot;git add/rm &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
#   (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
#
#       deleted:    file2.txt
#
no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)
D:\testgit&amp;gt;git checkout slave
D       file2.txt
Switched to branch 'slave'
D:\testgit&amp;gt;git status
# On branch slave
# Changes not staged for commit:
#   (use &amp;quot;git add/rm &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
#   (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
#
#       deleted:    file2.txt
#
no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)
D:\testgit&amp;gt;git add -A
D:\testgit&amp;gt;git status
# On branch slave
# Changes to be committed:
#   (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)
#
#       deleted:    file2.txt
#
D:\testgit&amp;gt;git checkout master
D       file2.txt
Switched to branch 'master'
D:\testgit&amp;gt;git status
# On branch master
# Changes to be committed:
#   (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)
#
#       deleted:    file2.txt
#
&lt;/pre&gt;
&lt;p&gt;So, our changes are not correlated with a branch until we commit them! Let&amp;#8217;s commit them to the master repository and confirm&amp;nbsp;that:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git commit -m &amp;quot;Deleted file2.txt&amp;quot;
[master 6f8749d] Deleted file2.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 file2.txt
D:\testgit&amp;gt;git status
# On branch master
nothing to commit, working directory clean
D:\testgit&amp;gt;dir file2.txt
[...]
File not found
D:\testgit&amp;gt;git checkout slave
Switched to branch 'slave'
D:\testgit&amp;gt;git status
# On branch slave
nothing to commit, working directory clean
D:\testgit&amp;gt;dir file2.txt
[...]
08/10/2013  05:59 pm                15 file2.txt
&lt;/pre&gt;
&lt;p&gt;This is interesting&amp;#8230; Let&amp;#8217;s try modifying the file2.txt (which does not exist to the master&amp;nbsp;branch):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git branch
  master
* slave
D:\testgit&amp;gt;echo new file2 contents &amp;gt; file2.txt
D:\testgit&amp;gt;git add .
D:\testgit&amp;gt;git status
# On branch slave
# Changes to be committed:
#   (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)
#
#       modified:   file2.txt
#
D:\testgit&amp;gt;git checkout master
error: Your local changes to the following files would be overwritten by checkout:
       file2.txt
Please, commit your changes or stash them before you can switch branches.
Aborting
&lt;/pre&gt;
&lt;p&gt;We won&amp;#8217;t be able to change the current branch until we commit the conflicting&amp;nbsp;change:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git commit -m &amp;quot;Modified file2&amp;quot;
[slave b5af832] Modified file2
 1 file changed, 1 insertion(+), 1 deletion(-)
D:\testgit&amp;gt;git checkout master
Switched to branch 'master'
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="remote-branches"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Remote&amp;nbsp;branches&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For each local repository you can define a number of remote repositories, or &lt;a class="reference external" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes"&gt;remotes&lt;/a&gt; as git calls them.
When you clone a repository from github.com, your local repository will have one remote, named origin. We will
try to add the same remote by hand. Let&amp;#8217;s suppose that we have created a repository in github.com named
testgit. After that we wil&amp;nbsp;issue:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git remote
D:\testgit&amp;gt;git remote add origin https://github.com/spapas/testgit.git
D:\testgit&amp;gt;git remote
origin
&lt;/pre&gt;
&lt;p&gt;So no we have one remote named origin that is linked with &lt;a class="reference external" href="https://github.com/spapas/testgit.git"&gt;https://github.com/spapas/testgit.git&lt;/a&gt;. Let&amp;#8217;s try to push our master
branch to the origin&amp;nbsp;remote:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git push origin master
Username for 'https://github.com': spapas
Password for 'https://spapas&amp;#64;github.com':
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 531 bytes, done.
Total 7 (delta 1), reused 0 (delta 0)
To https://github.com/spapas/testgit.git
 * [new branch]      master -&amp;gt; master
D:\testgit&amp;gt;git branch -r
  master
* slave
  remote/origin/master
&lt;/pre&gt;
&lt;p&gt;We see now that we have &lt;em&gt;three&lt;/em&gt; branches. Two local (master slave) and one remote (origin/master).  We will also add the slave remote&amp;nbsp;(origin/slave):&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git branch -r
  origin/master
  origin/slave
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s do a change to our local repository and then push them to the&amp;nbsp;remote:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;notepad file3.txt
D:\testgit&amp;gt;git add .
D:\testgit&amp;gt;git status
# On branch slave
# Changes to be committed:
#   (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)
#
#       modified:   file3.txt
#
D:\testgit&amp;gt;git commit -m &amp;quot;Changed file3.txt&amp;quot;
[slave ce3b7b9] Changed file3.txt
 1 file changed, 1 insertion(+), 1 deletion(-)
D:\testgit&amp;gt;git push origin slave
Username for 'https://github.com': spapas
Password for 'https://spapas&amp;#64;github.com':
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 299 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/spapas/testgit.git
   b5af832..ce3b7b9  slave -&amp;gt; slave
&lt;/pre&gt;
&lt;p&gt;Everything works as expected. The final thing to test is to try checking out a remote&amp;nbsp;branch:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git checkout master
Switched to branch 'master'
D:\testgit&amp;gt;echo new new file1 &amp;gt; file1.txt
D:\testgit&amp;gt;more file1.txt
 new new file1
D:\testgit&amp;gt;git checkout origin/master
M       file1.txt
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 6f8749d... Deleted file2.txt
D:\testgit&amp;gt;git status
# Not currently on any branch.
# Changes not staged for commit:
#   (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
#   (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
#
#       modified:   file1.txt
#
no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)
D:\testgit&amp;gt;more file1.txt
new new file1
&lt;/pre&gt;
&lt;p&gt;So, it seems that  when we check out the remote branch, we won&amp;#8217;t have any local branches, however the change we did to the file1.txt
is transfered just like when switching from one local repository to another. We can then add the changes and&amp;nbsp;commit:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git add .
D:\testgit&amp;gt;git commit
[detached HEAD 506674c] foo
 1 file changed, 1 insertion(+), 1 deletion(-)
 D:\testgit&amp;gt;git status
# Not currently on any branch.
nothing to commit, working directory clean
D:\testgit&amp;gt;git branch
* (no branch)
  master
  slave
&lt;/pre&gt;
&lt;p&gt;So we are working with an unnamed branch! We have to name it to be able to work without&amp;nbsp;problems:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
D:\testgit&amp;gt;git checkout -b named_branch
Switched to a new branch 'named_branch'
D:\testgit&amp;gt;git branch
  master
* named_branch
  slave
&lt;/pre&gt;
&lt;p&gt;Finally we may push again the named_branch to our remote&amp;nbsp;origin.&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Tue, 08 Oct 2013 13:20:00 +0300</pubDate><guid>tag:spapas.github.io,2013-10-08:2013/10/08/git-branches/</guid><category>git</category><category>github</category><category>branching</category></item><item><title>Using pelican to generate static sites on windows</title><link>http://spapas.github.io/2013/10/07/pelican-static-windows/</link><description>&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title first"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#introduction" id="id1"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#installing-pelican-and-generating-a-skeleton-for-your-site" id="id2"&gt;Installing pelican and generating a skeleton for your&amp;nbsp;site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#modifying-pelican-tools-for-windows" id="id3"&gt;Modifying pelican tools for&amp;nbsp;windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#configuration-of-your-skeleton-site" id="id4"&gt;Configuration of your skeleton site&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#settings" id="id5"&gt;Settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#themes" id="id6"&gt;Themes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#plugins" id="id7"&gt;Plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#hosting-in-github-pages" id="id8"&gt;Hosting in github&amp;nbsp;pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#publishing-changes" id="id9"&gt;Publishing&amp;nbsp;changes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id1"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.getpelican.com/en/3.3.0/"&gt;Pelican&lt;/a&gt; is a great static site generator. A static site generator is a tool that users a number of input files to
generate a complete html site. No database or server side scripting is needed for the resulting site, that&amp;#8217;s why
many such sites are hosted on &lt;a class="reference external" href="http://pages.github.com/"&gt;github pages&lt;/a&gt; (more on this&amp;nbsp;later).&lt;/p&gt;
&lt;p&gt;The input contains a number of html templates, css styles and the actual content of the site which most of the time is written in a
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Lightweight_markup_language"&gt;lightweight markup language&lt;/a&gt; like &lt;a class="reference external" href="http://docutils.sourceforge.net/rst.html"&gt;reStructuredText&lt;/a&gt; or &lt;a class="reference external" href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt;. The static site generator will generate the static pages by
inserting the content in the appropriate places in the&amp;nbsp;templates.&lt;/p&gt;
&lt;p&gt;In the following sections we will describe the installation of pelican on Windows
and the creation of the spapas.github.io&amp;nbsp;site.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-pelican-and-generating-a-skeleton-for-your-site"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2"&gt;Installing pelican and generating a skeleton for your&amp;nbsp;site&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The official pelican quickstart can be found in &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/getting_started.html"&gt;http://docs.getpelican.com/en/latest/getting_started.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To install pelican just&amp;nbsp;enter:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
&amp;gt;pip install pelican
&lt;/pre&gt;
&lt;p&gt;After installing pelican, I propose creating a parent directory that will
contain all your pelican sites, along with extra themes and plugins like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pelican/
  ├── pelican-themes
  ├── other-pelican-theme
  ├── spapas.github.io
  └── other-sites
&lt;/pre&gt;
&lt;p&gt;After creating the pelican directory just go in it with a command line and run the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;pelican-quickstart&lt;/span&gt;&lt;/tt&gt; command.
It will ask you a number of questions, take a look at how I did answer&amp;nbsp;these:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
pelican&amp;gt;pelican-quickstart
Welcome to pelican-quickstart v3.2.2.

This script will help you create a new Pelican-based website.

Please answer the following questions so this script can generate the files
needed by Pelican.


&amp;gt; Where do you want to create your new web site? [.] spapas.github.io
&amp;gt; What will be the title of this web site? Test github.io
&amp;gt; Who will be the author of this web site? Serafeim
&amp;gt; What will be the default language of this web site? [en]
&amp;gt; Do you want to specify a URL prefix? e.g., http://example.com   (Y/n)
&amp;gt; What is your URL prefix? (see above example; no trailing slash) http://spapas.github.io
&amp;gt; Do you want to enable article pagination? (Y/n)
&amp;gt; How many articles per page do you want? [10]
&amp;gt; Do you want to generate a Makefile to easily manage your website? (Y/n) n
&amp;gt; Do you want an auto-reload &amp;amp; simpleHTTP script to assist with theme and site development? (Y/n) n
Done. Your new project is available at C:\progr\py\pelican\spapas.github.io
&lt;/pre&gt;
&lt;p&gt;After that, you will have a pelican/spapas.github.io folder that will contain the following&amp;nbsp;content:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
spapas.github.io/
  ├── content
  ├── output
  ├── pelicanconf.py
  └── publishconf.py
&lt;/pre&gt;
&lt;p&gt;The content folder will contain your content (rst or markdown), the output will contain the generated html after you run pelican for your site.
The &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; will have a number of options for the generation of the development version of your site while the &lt;tt class="docutils literal"&gt;publishconf.py&lt;/tt&gt; will override some of the options
of &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; before generating the production version of your site that will actually be uploaded to github&amp;nbsp;pages.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="modifying-pelican-tools-for-windows"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3"&gt;Modifying pelican tools for&amp;nbsp;windows&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pelican uses a Makefile and a unix shell script to generate the static html files and start an http server for development.
Because I prefer to use windows, I answered no to the questions of generating these when pelican-quickstarte asked me.
Instead I have included the following files inside the spapas.github.io&amp;nbsp;directory:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pelrun.bat&lt;/tt&gt;, to generate the content for your debug site in the output&amp;nbsp;directory:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
pelican content --debug --autoreload  --output output --settings pelicanconf.py
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pelserve.bat&lt;/tt&gt;, to localy serve the generated debug&amp;nbsp;site:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
pushd output
python -m pelican.server
popd
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pelpub.bat&lt;/tt&gt;, to generate the production site in the output&amp;nbsp;directory:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;
pelican content --output output --settings publishconf.py
&lt;/pre&gt;
&lt;p&gt;Now, when you want to develop your site locally,&amp;nbsp;enter:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
spapas.github.io&amp;gt;start pelrun.bat
spapas.github.io&amp;gt;start pelserv.bat
&lt;/pre&gt;
&lt;p&gt;If everything was ok until now, you can visit &lt;a class="reference external" href="http://127.0.0.1:8000"&gt;http://127.0.0.1:8000&lt;/a&gt; and will get the following&amp;nbsp;output:&lt;/p&gt;
&lt;img alt="all ok!" src="/images/site1.png" style="width: 780px;" /&gt;
&lt;p&gt;Because of the -r option that is used in &lt;tt class="docutils literal"&gt;pelrun.bat&lt;/tt&gt; whenever you do a change (for instance when you add an rst file in the content directory)
it will be discovered and the output will be changed&amp;nbsp;immediately!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration-of-your-skeleton-site"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id4"&gt;Configuration of your skeleton&amp;nbsp;site&lt;/a&gt;&lt;/h2&gt;
&lt;div class="section" id="settings"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5"&gt;Settings&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There is a number of settings that you may configure in your site. The pelican settings reference can be found here: &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/settings.html"&gt;http://docs.getpelican.com/en/latest/settings.html&lt;/a&gt;.
The pelicanconf.py and publishconf.py for this site can be found&amp;nbsp;here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/spapas/spapas.github.io/blob/source/pelicanconf.py"&gt;https://github.com/spapas/spapas.github.io/blob/source/pelicanconf.py&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/spapas/spapas.github.io/blob/source/publishconf.py"&gt;https://github.com/spapas/spapas.github.io/blob/source/publishconf.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The most important difference is the RELATIVE_URLS directive which must be True to the debug and False to the&amp;nbsp;production.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="themes"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6"&gt;Themes&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Beyond the default pelican theme, you can use configure pelican to use various other themes. To enable them, go to your pelican parent directory and clone the pelican-themes github&amp;nbsp;repository:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
pelican&amp;gt;git clone https://github.com/getpelican/pelican-themes.git
&lt;/pre&gt;
&lt;p&gt;After that, you may select your theme from&amp;nbsp;pelicanconf.py:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
THEME = &amp;quot;../pelican-themes/theme-name&amp;quot;
&lt;/pre&gt;
&lt;p&gt;In my configuration, I am using the Octopress Theme for Pelican, which you may get from here &lt;a class="reference external" href="https://github.com/duilio/pelican-octopress-theme"&gt;https://github.com/duilio/pelican-octopress-theme&lt;/a&gt;. Just clone it to your
pelican directory and refer to it as&amp;nbsp;above.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="plugins"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7"&gt;Plugins&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Pelican has a number of plugins. To enable them, go to your pelican parent directory and clone the pelican-plugins github&amp;nbsp;repository:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
pelican&amp;gt;git clone https://github.com/getpelican/pelican-plugins.git
&lt;/pre&gt;
&lt;p&gt;After that, you may add the following two lines to your&amp;nbsp;pelicanconf.py:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
PLUGIN_PATH = '../pelican-plugins'
PLUGINS = ['a-plugin']
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="hosting-in-github-pages"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id8"&gt;Hosting in github&amp;nbsp;pages&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To host your static site in github pages you must first of all create a repository named
username.github.io (for instance spapas.github.io) from&amp;nbsp;github.&lt;/p&gt;
&lt;p&gt;Then, generate your production&amp;nbsp;output:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
spapas.github.io&amp;gt;pelpub.bat
&lt;/pre&gt;
&lt;p&gt;Finally, go to your output directory, create a git repository, add everything and push it to your&amp;nbsp;repository:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
spapas.github.io\output&amp;gt;git init
spapas.github.io\output&amp;gt;git add .
spapas.github.io\output&amp;gt;git commit -m Initial
spapas.github.io\output&amp;gt;git remote add origin https://github.com/spapas/spapas.github.io.git
spapas.github.io\output&amp;gt;git push origin master --force
&lt;/pre&gt;
&lt;p&gt;The &amp;#8212;force is to overwrite any previous versions - you don&amp;#8217;t care about version control on your output (but you want it on your&amp;nbsp;source).&lt;/p&gt;
&lt;p&gt;You can now visit &lt;a class="reference external" href="http://username.github.io"&gt;http://username.github.io&lt;/a&gt; and see your statically generated site&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t forget to add your source to the version control! To do that, add a .gitignore file in your pelican/username.github.io direcory
containing the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
output
&lt;/pre&gt;
&lt;p&gt;The above file will ignore the contents of the output directory from version control. After that, do the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
spapas.github.io&amp;gt;git init
spapas.github.io&amp;gt;git add .
spapas.github.io&amp;gt;git commit -m Initial
spapas.github.io&amp;gt;git branch -m master source
spapas.github.io&amp;gt;git remote add origin https://github.com/spapas/spapas.github.io.git
spapas.github.io&amp;gt;git push origin source
&lt;/pre&gt;
&lt;p&gt;The above will rename the master branch to source, will attach the origin remote to &lt;a class="reference external" href="https://github.com/spapas/spapas.github.io.git"&gt;https://github.com/spapas/spapas.github.io.git&lt;/a&gt; and will push the source
branch to it. Now you will have two branches in your username.github.io repository. One
named origin/master that will be your actual site and will be displayed through &lt;a class="reference external" href="http://username.github.io"&gt;http://username.github.io&lt;/a&gt; and one named origin/source that will contain the source of your&amp;nbsp;site.&lt;/p&gt;
&lt;p&gt;To learn more about branches and remotes you may check out &lt;a class="reference external" href="http://spapas.github.io/2013/10/08/git-branches/"&gt;the git branches article&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="publishing-changes"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id9"&gt;Publishing&amp;nbsp;changes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Whenever you need to publish a new article or do changes to an existing one, you need to do the&amp;nbsp;following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Run pelpub.bat to create the new&amp;nbsp;output&lt;/li&gt;
&lt;li&gt;Add/commit and push changes from your pelican site(source) folder to the source&amp;nbsp;remote&lt;/li&gt;
&lt;li&gt;Add/commit and push changes from your output folder to the master&amp;nbsp;remote&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To help with this, here&amp;#8217;s a ghdeploy.bat file that does all the&amp;nbsp;above:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
call pelpub.bat
git add -A
git commit -m &amp;quot;Deploying changes&amp;quot;
git push origin source
pushd output
git add -A
git commit -m &amp;quot;Deploying changes&amp;quot;
git push origin master
popd
&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;ve followed this far, by running &lt;tt class="docutils literal"&gt;pelpub.bat&lt;/tt&gt; you&amp;#8217;ll need to enter your github repository credentials (twice) and then
everything (source and master) will be deployed! To make things even better, I propose to use &lt;a class="reference external" href="https://help.github.com/articles/generating-ssh-keys/"&gt;ssh based authentication&lt;/a&gt;
to your github account and add new remote names to your source and master by running the&amp;nbsp;following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;
git remote add origin2 git&amp;#64;github.com:spapas/spapas.github.io.git
&lt;/pre&gt;
&lt;p&gt;to your pelican site and the output directories. After you change ghdeploy.bat to use &lt;tt class="docutils literal"&gt;origin2&lt;/tt&gt; instead of &lt;tt class="docutils literal"&gt;origin&lt;/tt&gt; you&amp;#8217;ll be
able to deploy everything with just running it without entering any&amp;nbsp;credentials!&lt;/p&gt;
&lt;/div&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Serafeim Papastefanos</dc:creator><pubDate>Mon, 07 Oct 2013 10:20:00 +0300</pubDate><guid>tag:spapas.github.io,2013-10-07:2013/10/07/pelican-static-windows/</guid><category>static-html</category><category>github.io</category><category>github</category><category>pelican</category><category>windows</category><category>python</category><category>github-pages</category><category>rst</category></item></channel></rss>