<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><title>Protractile</title><link href="http://amirouche.github.com/blog/" rel="alternate" /><id>http://amirouche.github.com/blog/</id><updated>2013-02-23T00:00:00+01:00</updated><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/protractileaigu" /><feedburner:info uri="protractileaigu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>protractileaigu</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry><title>Cross compiling a Gentoo</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/GF1DFh5weTQ/cross-compiling-a-gentoo.html" rel="alternate" /><updated>2013-02-23T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-02-23:cross-compiling-a-gentoo.html</id><summary type="html">&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This article is about cross compiling a Gentoo/Funtoo not building a Rasberry Pi Gentoo/Funtoo, if what you want is a Gentoo on your raspberry follow the white rabbit on &lt;a class="reference external" href="http://wiki.gentoo.org"&gt;wiki.gentoo.org&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If a machine can run a GNU/Linux you don't need to do cross-compilation but if the machine is not powerful enough you will still want to compile the binaries in another more powerful machine which means building a cross-compilation toolchain. Gentoo provides a script to do that backed by Portage, it builds a GCC compiler that run on your machine which is called the &lt;em&gt;host&lt;/em&gt; and builds binaries for the other machine called the &lt;em&gt;target&lt;/em&gt;. But no all sources can be cross compiled, some do, some don't, you need a specific configuration to be able to cross compile something and sometime it will just not compile like Python (I only tested 2.7.3). So instead what can be done is fake that we compile on the target so that the build process operate as if it was on the target machine, this can been done with a a qemu chroot or a &lt;cite&gt;proot &amp;lt;http://proot.me/&amp;gt;&lt;/cite&gt; qemu and a bit of portage tweaking ;). This methods divide nearly by 6 the time needed to compile the kernel on my quad core i5.&lt;/p&gt;
&lt;p&gt;Here what I propose it to build a Funtoo, Portage backed distribution for Raspberry Pi with x86_64 as host. It basicaly goes like this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Build crossdev, proot and qemu with support for the target in this case arm&lt;/li&gt;
&lt;li&gt;Build cross compiler on x86_64 and cross environnement for armv6j&lt;/li&gt;
&lt;li&gt;Emerge &amp;#64;system&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this stage, you will have what is called a «stage 3», you can then emerge whatever you want and use the target directory as the base of a root filesystem of any armv6j backed machine.&lt;/p&gt;
&lt;div class="section" id="ninja-cli-dance"&gt;
&lt;h2&gt;Ninja cli dance&lt;/h2&gt;
&lt;p&gt;Grab a hot cup of coffee and first emerge crossdev, create a dummy overlay for it, call it &lt;tt class="docutils literal"&gt;crossoverlay&lt;/tt&gt; don't forget to add it as first path in &lt;tt class="docutils literal"&gt;PORTDIR_OVERLAY&lt;/tt&gt; of your &lt;tt class="docutils literal"&gt;make.conf&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;While you are in &lt;tt class="docutils literal"&gt;make.conf&lt;/tt&gt; you can add the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;QEMU_SOFTMMU_TARGETS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;arm&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;QEMU_USER_TARGETS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;arm&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now emerge proot and qemu:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;emerge -q proot qemu
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;qemu is an emulator and &lt;a class="reference external" href="http://proot.me/"&gt;proot&lt;/a&gt; some kind of improved-with-powerful-magic chroot.&lt;/p&gt;
&lt;p&gt;Bootstrap the crosstools and target root filesystem with crossdev:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;crossdev -S -s4 arm-hardfloat-linux-gnueabi
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now prepare the cross-environnement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi/usr/
cp -r /usr/portage .
mkdir -p share/portage/config/sets
cp /usr/share/portage/config/make.globals /usr/arm-hardfloat-linux-gnueabi/usr/share/portage/config/
&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi/var
git clone git://github.com/amirouche/funtoo-overlay.git amirouche
&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi/etc
rm make.profile
ln -s ../var/amirouche/profiles/raspberrypi make.profile
emerge-arm-hardfloat-linux-gnueabi -q binutils
emerge-arm-hardfloat-linux-gnueabi -q glibc
emerge-arm-hardfloat-linux-gnueabi -q gcc
emerge-arm-hardfloat-linux-gnueabi -q portage
emerge-arm-hardfloat-linux-gnueabi -qO libtool
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Portage will fail it's not significant. Open &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/arm-hardfloat-linux-gnueabi/etc/portage/make.conf&lt;/span&gt;&lt;/tt&gt; and comment the &lt;tt class="docutils literal"&gt;ROOT&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;PKGDIR&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;PORTAGE_TMPDIR&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;PKG_CONFIG_PATH&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;CBUILD&lt;/tt&gt; and their should only be &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/host-rootfs/var/amirouche&lt;/span&gt;&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;PORTDIR_OVERLAY&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Proot needs &lt;tt class="docutils literal"&gt;libgcc_s.so.1&lt;/tt&gt; to work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi
cp usr/lib/gcc/arm-hardfloat-linux-gnueabi/4.6.3/libgcc_s.so.1 lib
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Until Python is compiled inside the new environnement we will use the host Python:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi/usr/bin
ln -s ../../host-rootfs/usr/bin/python2.7
ln -s ../../host-rootfs/usr/bin/python2.7 python
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Change PS1 in the chroot to prevent errors in other consoles:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;export PS1=\&amp;quot;(qemu proot arm-hardfloat-linux-gnueabi) \$PS1\&amp;quot;&amp;quot;&lt;/span&gt; &amp;gt;&amp;gt; /usr/arm-hardfloat-linux-gnueabi/etc/bash/bashrc
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now proot in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/arm-hardfloat-linux-gnueabi&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/arm-hardfloat-linux-gnueabi
proot -r . -w / -Q qemu-arm /bin/bash
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now compile using the target compiler inside the proot environnement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;emerge -q @system
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Is not that easy but I'm sure you will succeed at solving the issues that may arise ;)&lt;/p&gt;
&lt;p&gt;Create an archive and keep it safe somewhere, exit the target environnement and execute on the host the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/
tar -pczf arm-hardfloat-linux-gnueabi.tar.gz arm-hardfloat-linux-gnueabi/
mv arm-hardfloat-linux-gnueabi.tar.gz /home/
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your armv6j stage 3 is ready!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="todo"&gt;
&lt;h2&gt;TODO&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Create a qemu image&lt;/li&gt;
&lt;li&gt;Continue the install take inspiration from gentoo's &lt;a class="reference external" href="http://wiki.gentoo.org/wiki/Raspberry_Pi_Quick_Install_Guide"&gt;Raspberry Pi Quick Install Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Setting up distcc&lt;/li&gt;
&lt;li&gt;Make patches to make &lt;tt class="docutils literal"&gt;emerge &amp;#64;system&lt;/tt&gt; working with almost empty tree.&lt;/li&gt;
&lt;li&gt;Investigate why overriding cross environnement PATH and using the cross compiler will fail to properly build some softwares (e.g. eix)&lt;/li&gt;
&lt;li&gt;Patch crossdev to support custom profiles&lt;/li&gt;
&lt;li&gt;Setup a cross root environnement from a stage 3&lt;/li&gt;
&lt;li&gt;Patch metro to support this kind of build&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/GF1DFh5weTQ" height="1" width="1"/&gt;</summary><category term="code" /><category term="funtoo" /><feedburner:origLink>http://amirouche.github.com/blog/cross-compiling-a-gentoo.html</feedburner:origLink></entry><entry><title>Installer Funtoo</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/T1fMnp85WIs/installer-funtoo.html" rel="alternate" /><updated>2013-02-16T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-02-16:installer-funtoo.html</id><summary type="html">&lt;p&gt;Funtoo est un fork gentil de &lt;a class="reference external" href="http://www.gentoo.org"&gt;Gentoo&lt;/a&gt;. Gentoo est &lt;em&gt;la&lt;/em&gt; distribution source, par excellence,
c'est à dire que tout est installer depuis les sources des logiciels. La compilation depuis les sources
permet d'avoir un OS plus puissant car les binaires peuvent être optimisés pour la machine. L'autre
chose qui rend une Gentoo puissante sont les drapeaux d'utilisation aka. «USE flags» qui permettent de configurer
la compilation des logiciels afin de n'inclure que ce que dont vous avez besoin et donc encore une fois rendre
votre OS plus rapide. Un autre interet c'est la disponibilité quasi immediate dans les recettes pour compiler
le dernier logiciel à la mode, même si il est pas encore stabilisé.&lt;/p&gt;
&lt;p&gt;Ce qui fait sa force fait aussi sa faiblesse: la compilation ça prend du temps. L'autre difficulté est la mise à jour des logiciels de bases GCC, glibc mais qui a dit que les mise à jours de distribution fonctionnaient ?&lt;/p&gt;
&lt;p&gt;Si vous voulez découvrir ce qui fait un distribution GNU/Linux c'est l'idéal. Si vous voulez découvrir &lt;em&gt;comment&lt;/em&gt; on fait une distribution il faut se tourner vers &lt;a class="reference external" href="http://www.linuxfromscratch.org/"&gt;LinuxFromScratch&lt;/a&gt; pour laquelle il doit y a voir une traduction en français.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.funtoo.org/wiki/Welcome"&gt;Funtoo&lt;/a&gt; est un fork realisé par l'initateur du projet Gentoo, où ont lieu des modifications ou vont avoir lieu des modifications majeurs, pour le moment il y a:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Metro, un logiciel qui permet de construire une distribution basé sur Portage (le gestionnaire de paquet de la Gentoo) utilisé par Gentoo et Funtoo&lt;/li&gt;
&lt;li&gt;Gestion des profiles amélioré avec la possibilité d'ajouter des profiles Mix-In qui sont des additions à n'importe quelles autre profiles. Un profile Portage renseigne un certains nombres d'informations sur la distribution, drapeaux d'utilisation de base, masques pour les recettes pour eviter l'utilisation de recettes non stables et ceci pour différentes plateformes (x86, x86_64, arm, ppc etc...) et pour différente utilisation (desktop, server, workstation). Les MixIn vont permettre de manière transversale d'ajouter des fonctions à votre profil (Gnome, Kde, audio, video etc...) pour simplifier la configuration de votre OS.&lt;/li&gt;
&lt;li&gt;Les mise à jours de la configuration Grub automatique avec un fichier de configuration pour les humains ;)&lt;/li&gt;
&lt;li&gt;Des scripts réseaux améliorés&lt;/li&gt;
&lt;li&gt;L'overlay de la distribution, ensemble de recettes de compilation et profiles sont synchronisé avec celui de Gentoo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Funtoo utilise aussi github et donc git pour herbergé l'overlay.&lt;/p&gt;
&lt;p&gt;Pour Funtoo il y a une documentation en &lt;a class="reference external" href="https://www.funtoo-quebec.org/wiki/index.php/Installation_de_Gentoo"&gt;français&lt;/a&gt; aussi, ainsi qu'un &lt;a class="reference external" href="https://www.funtoo-quebec.org/wiki/index.php/Premiers_pas_avec_Funtoo"&gt;guide de demarrage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;«On the seventh day, God saw the world had already been outdated, so he did a god&amp;#64;heaven# eix-sync &amp;amp;&amp;amp; emerge -uDNav &amp;#64;world &amp;amp;&amp;amp; exit42» ~ Genesis on Gentoo&lt;/em&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/T1fMnp85WIs" height="1" width="1"/&gt;</summary><category term="funtoo" /><feedburner:origLink>http://amirouche.github.com/blog/installer-funtoo.html</feedburner:origLink></entry><entry><title>AdminNext: A new API</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/wp_raGSi1i8/django-admin-next-a-new-api.html" rel="alternate" /><updated>2013-01-05T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-01-05:django-admin-next-a-new-api.html</id><summary type="html">&lt;p&gt;Following the first post about
&lt;a class="reference external" href="http://amirouche.github.com/blog/django-admin-next.html"&gt;AdminNext&lt;/a&gt;,
this posts dives further the idea of another API to build an admin area.&lt;/p&gt;
&lt;p&gt;In a previous version of this article I tried to dive the &lt;em&gt;user features API&lt;/em&gt;
idea, it wasn't that interesting. The part about user features that I still
find somewhat interesting resulted in an article with the same name.&lt;/p&gt;
&lt;div class="section" id="model-centric"&gt;
&lt;h2&gt;Model centric&lt;/h2&gt;
&lt;p&gt;In the previous post I was talking about a groups centric admin, this was
badly done. The story goes like this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I was thinking about the admin and discovered that it was model centric&lt;/li&gt;
&lt;li&gt;Why is it model centric ?&lt;/li&gt;
&lt;li&gt;Can it be something else ?&lt;/li&gt;
&lt;li&gt;What would it be ?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the same time I was wondering about the fact that the admin API was bare
metal the features it provides and the code that generate it which lead me
to the &lt;em&gt;user feature&lt;/em&gt; thing and composite views as way to abstract the features
each view provides.&lt;/p&gt;
&lt;p&gt;Putting all this together, I'm looking for an API that meets this goals:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;non-model centric&lt;/li&gt;
&lt;li&gt;focused on user&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This lead me to the group-centric admin, because:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;groups relate to users&lt;/li&gt;
&lt;li&gt;groups relate to permissions&lt;/li&gt;
&lt;li&gt;permissions relate to actions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And groups can relate to features without requiring them to be linked to
an a permission. For instance an user can be part of group because he is
part of community and as such require a particular treatment like say
I subscribe to a subreddit, I get it on frontpage, the subreddit is available
to everybody but as a member of the subreddit I can access it easily.&lt;/p&gt;
&lt;p&gt;Group is in a gray area, it's a user feature but also a code feature,
so I was back at code as a rail for thinking which was exactly what
I didn't want to do.&lt;/p&gt;
&lt;p&gt;Even more mistakes, in my previous attemps to draw a new API, I focused too
much on groups as UI or how an admin that use more the group concept would look
like so I had trouble to find a coherant API, while now it seems to me
that I should have started from &lt;em&gt;permissions&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Another thing, current django admin does rely on &lt;em&gt;permissions&lt;/em&gt; and &lt;em&gt;groups&lt;/em&gt;
to customize the experience of each user, but this not done in way that can
make the experience better, at least what I think is better, like it's
explained in the following part.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="permission-centric-api"&gt;
&lt;h2&gt;Permission centric API&lt;/h2&gt;
&lt;p&gt;Like I said above, before I focused too much on groups because I think it's
central in an admin experience, but the foundation of a group is users of
course, but in the point of view of code it's permissions.&lt;/p&gt;
&lt;div class="section" id="api-overview"&gt;
&lt;h3&gt;API overview&lt;/h3&gt;
&lt;p&gt;What ever the admin there is:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;menu or several menus&lt;/li&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;navigate, explore, filter models&lt;/li&gt;
&lt;li&gt;CRUD operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the most important thing the ability to &lt;strong&gt;stay focused on the task&lt;/strong&gt;
which can be achived through &lt;strong&gt;separation of concerns&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="api-wireframe"&gt;
&lt;h3&gt;API wireframe&lt;/h3&gt;
&lt;div class="section" id="about-writring-apis"&gt;
&lt;h4&gt;About writring APIs&lt;/h4&gt;
&lt;p&gt;When I build an API I start from the user part of the API, I write things like
I would like to write them myself. This also translates in me doing the same
thing when I actually write the code which means I focus on usability before
focusing on features which for instance lead me to write a declarative API
but without any means to do the same thing otherwise. So writring the API
is a way to get an idea of the &lt;em&gt;why&lt;/em&gt; and &lt;em&gt;what&lt;/em&gt; but not the &lt;em&gt;how&lt;/em&gt; which needs
further thinking.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="context"&gt;
&lt;h4&gt;Context&lt;/h4&gt;
&lt;p&gt;The site for which I will mock an API is named «Cabernet Cheese Chop». The
website is a frontend for consumers but also a social network for cheese
enthusiasts and allows each shop owner to run their &lt;em&gt;boutique&lt;/em&gt;. Notable
features are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Cheese, wine, bread and butter spotlight, it's somekind of magazine for
all things related to the restaurant suite.&lt;/li&gt;
&lt;li&gt;A social network in which consumers and owners interacts together sharing
and caring for the finest tastes...&lt;/li&gt;
&lt;li&gt;ERP thing that allows to manage supplies, keep in touch with their local
community and everything that needs to be done to keep a business running.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course all this is inter-mixed in an awesome way so that the experience is
awesome.&lt;/p&gt;
&lt;p&gt;The example is in purpose federation-like, a big entity and many related sub
entities, so that it match most websites while still being possible to relate
to simple websites where there is only one group of people running one business.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="writring-the-backend"&gt;
&lt;h4&gt;Writring the backend&lt;/h4&gt;
&lt;p&gt;What we are interested in here is to write a backend that allows every people
taking part in this entreprise to deal with their matters. I won't write every
backend features so I will focus on the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;strong&gt;Local community manager&lt;/strong&gt; answers questions regarding the local shop,
gives a hand in the magazine and also keeps an eye over the social network.&lt;/blockquote&gt;
&lt;p&gt;This is already a bit complex since there is three user stories only for one
job.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Without further ado&lt;/em&gt; let's write the class that will represents the
&lt;em&gt;local shop support&lt;/em&gt; story:&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;LocalShopSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;verbose_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;shop support&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SupportTicketExplore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SupportTicketAnswer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;dashboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IncomingTickets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SupportTicketFeedback&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;filter_queryset&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;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&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;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Except it uses a
&lt;a class="reference external" href="http://docs.zope.org/zope.interface/_modules/zope/interface/declarations.html#implements"&gt;syntax that is not supported by Python 3&lt;/a&gt;,
it draws a canvas for how one can define backend features. Permissions
don't appear in this &lt;tt class="docutils literal"&gt;Feature&lt;/tt&gt; because it they are &lt;em&gt;inherited&lt;/em&gt; from
the &lt;tt class="docutils literal"&gt;includes&lt;/tt&gt;. Let's define the &lt;tt class="docutils literal"&gt;includes&lt;/tt&gt;:&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;SupportTicketExplore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;ChangeList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SupportTicketChangeList&lt;/span&gt;

    &lt;span class="c"&gt;# inherited from SupportTicketChangeList&lt;/span&gt;
    &lt;span class="c"&gt;# permissions = [&amp;#39;support.ticket.can_read&amp;#39;,]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SupportTicketAnswer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TicketAnswer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestForFeedbackOnTicket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# inherited from TicketAnswer&lt;/span&gt;
    &lt;span class="c"&gt;# permissions = [&amp;#39;support.ticket.can_answer&amp;#39;,]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can go on and on with more classes but everything could have
been done in one 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;LocalShopSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Feature&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;support&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ticket&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChangeList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseChangeList&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;list_display&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;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;kind&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nb"&gt;filter&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;state&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;kind&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;order_by&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;submit_date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;last_seen&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;last_answer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;permissions&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;support.ticket.can_read&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;TicketAnswer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelChangeView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;anwser&amp;#39;&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;AddCommentForm&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;support/tickets/add_comment.html&amp;#39;&lt;/span&gt;

        &lt;span class="n"&gt;permissions&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;support.ticket.can_anwser&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;RequestForFeedbackOnTicket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelAction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;in_bulk&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;def&lt;/span&gt; &lt;span class="nf"&gt;action&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="n"&gt;queryset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;queryset&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;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Ticket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STATE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;REQUEST_FOR_FEEDBACK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TicketAnswer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestForFeedbackOnTicket&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;IncomingsTickets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ObjectListDashBoard&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;incomings tickets&amp;#39;&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_queryset&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;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;queryset&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;IncomingsTickets&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;filter_queryset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c"&gt;# the queryset is already filtered for this user&lt;/span&gt;
            &lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state__in&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Ticket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STATE&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="n"&gt;Ticket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STATE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NEEDS_REPLY&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;queryset&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SupportTicketFeedback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ObjectListDashBoard&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;feedback&amp;#39;&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;queryset&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;queryset&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;IncomingsTickets&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;filter_queryset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&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;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Ticket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STATE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;REQUEST_FOR_FEEDBACK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback_set&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="n"&gt;dashboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IncomingTickets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SupportTicketFeedback&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;filter_queryset&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;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
         &lt;span class="n"&gt;queryset&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;LocalShopSupport&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;filter_queryset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&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;queryset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How subclasses of &lt;tt class="docutils literal"&gt;Feature&lt;/tt&gt; are pulled together is more simple to explain,
when the application boots it discover somehow all the &lt;tt class="docutils literal"&gt;Feature&lt;/tt&gt; classes,
gather the needed permissions for each features, given that informations it
will match features to regroup them based on groups' permissions. If a
feature is a subset of another, the feature that has more permissions (and
probably features) will be associated with the group. At the end all features
should be associated with groups if it's not the case then the remaining
features are again matched against the groups but only considering the subset
of remaining features. This process continue until there is no more lonely
features or features can not be matched with a group. In this case, the feature
will only be available in superuser tab.&lt;/p&gt;
&lt;blockquote&gt;
« Experienced programmers don't use design patterns. Design patterns use them. » &lt;a class="reference external" href="http://programmers.stackexchange.com/questions/141854/design-patterns-do-you-use-them/141879#141879"&gt;Lunivore in Design patterns - do you use them?&lt;/a&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/wp_raGSi1i8" height="1" width="1"/&gt;</summary><category term="code" /><category term="python" /><category term="django" /><feedburner:origLink>http://amirouche.github.com/blog/django-admin-next-a-new-api.html</feedburner:origLink></entry><entry><title>User features</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/9pzPgwq3i6Y/user-features.html" rel="alternate" /><updated>2013-01-05T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-01-05:user-features.html</id><summary type="html">&lt;p&gt;This doen't look like a widespread idea to say the least. I'm not sure the wording
express my &lt;em&gt;feeling&lt;/em&gt;, a definition might help:&lt;/p&gt;
&lt;blockquote&gt;
An &lt;em&gt;user feature&lt;/em&gt; is a particular ability an user has in his or her use of
a software&lt;/blockquote&gt;
&lt;p&gt;Examples of user features follow:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ability to explore, filter, navigate the objects related to a particular task&lt;/li&gt;
&lt;li&gt;Ability to edit objects in the context of a particular task&lt;/li&gt;
&lt;li&gt;Ability to have and give feedback about a particular action or task or group of tasks&lt;/li&gt;
&lt;li&gt;Ability to have an overview regarding the state of a project&lt;/li&gt;
&lt;li&gt;Ability to move to another task quickly&lt;/li&gt;
&lt;li&gt;Ability to customise UX/UI&lt;/li&gt;
&lt;li&gt;Ability to not loose sight of the current task&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those are a bit generic and grow out of my reflexion about django admin. I will try something else:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ability to pay for something&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I'm stuck! Maybe this is not an interesting concept. The thing that looks to be the
most related is &lt;em&gt;user stories&lt;/em&gt;. Here is the abstract definition from Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In software development and product management, a user story is &lt;strong&gt;one or more sentences in the everyday or business language of the end user or user of a system that capture what a user does or needs to do as part of his or her job function&lt;/strong&gt;. User stories are used with Agile software development methodologies as the basis for defining the functions a business system must provide, and to facilitate requirements management. &lt;strong&gt;It captures the 'who', 'what' and 'why' of a requirement&lt;/strong&gt; in a simple, concise way, often limited in detail by what can be hand-written on a small paper notecard. User stories are written by or for the business user as that user's primary way to influence the functionality of the system being developed. User stories may also be written by developers to express non-functional requirements (security, performance, quality, etc.),[1] though primarily it is the task of a product manager to ensure user stories are captured.&lt;/p&gt;
&lt;p&gt;From &lt;a class="reference external" href="http://en.wikipedia.org/wiki/User_story"&gt;User story&lt;/a&gt; article from Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Emphase is mine.&lt;/p&gt;
&lt;p&gt;Example user stories are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I can browser stuff listing and click buy to add it to the shopping cart&lt;/li&gt;
&lt;li&gt;I can browser recent comments and click delete&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Based on this definition, &lt;em&gt;user features&lt;/em&gt; are &lt;em&gt;generic stories&lt;/em&gt; or
&lt;em&gt;abstract stories&lt;/em&gt;.
which allows to think on a higher level and probably find other patterns and
code abstractions.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/9pzPgwq3i6Y" height="1" width="1"/&gt;</summary><category term="code" /><feedburner:origLink>http://amirouche.github.com/blog/user-features.html</feedburner:origLink></entry><entry><title>Django AdminNext</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/XLMDfnSF31Y/django-admin-next.html" rel="alternate" /><updated>2013-01-01T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-01-01:django-admin-next.html</id><summary type="html">&lt;p&gt;In an attempt to chime into Django developement but first because I was
interested by the project and that I think I have a solution for
Django Admin. It may seem very pretencious and arogant to say that,
when I first posted my message on &lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups#!forum/django-developers"&gt;django-developper&lt;/a&gt;
I didn't knew the revamp was a subject of interest in the Django
community until watching some djangocon videos and writring this article.&lt;/p&gt;
&lt;p&gt;So instead of trying to build something and then see if it works, I decided
to start it all over again, starting by reading
&lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/internals/contributing/"&gt;Django's guide to contribute&lt;/a&gt;
and «&lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/internals/contributing/new-contributors/"&gt;Advice for new contributors&lt;/a&gt;»
in particular those got my attention:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Analyze tickets’ context and history&lt;/li&gt;
&lt;li&gt;Start small: It’s easier to get feedback on a little issue than on a big one.&lt;/li&gt;
&lt;li&gt;If you’re going to engage in a big task, make sure that your idea has support
first&lt;/li&gt;
&lt;li&gt;Be bold! Leave feedback!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, that is what follows.&lt;/p&gt;
&lt;div class="section" id="context"&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;div class="section" id="history"&gt;
&lt;h3&gt;History&lt;/h3&gt;
&lt;p&gt;Current admin project named &lt;a class="reference external" href="https://code.djangoproject.com/wiki/NewformsAdminBranch"&gt;new-forms-admin&lt;/a&gt;
was built primarly to make use of new-forms and add extra customization hooks.&lt;/p&gt;
&lt;p&gt;So new-forms-admin was part of the deprecation of old-forms which, I think, was
part of the refactoring of models and queryset. I think they most notably
decoupled form fields from their html representation, widgets, but I'm not sure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="user-features"&gt;
&lt;h3&gt;User features&lt;/h3&gt;
&lt;p&gt;Django was created in a newspaper and I think that it was primarly meant to be
a CMS framework and since the beggining the admin was one of the most powerful
feature.&lt;/p&gt;
&lt;p&gt;But the web evolved, most notably the web uses evolved, the needs evolved,
even «CMS» application evolved, so one can not think about the admin without
thinking about Django uses and the web in general.&lt;/p&gt;
&lt;p&gt;First there is a lot of applications type CRM, ERP, e-commerce,
e-administration (or e-governement), any other business specific application,
all this can be summed up in terms:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;objects inspections: search, filtering, navigation&lt;/li&gt;
&lt;li&gt;input data: crud operations and ordering things&lt;/li&gt;
&lt;li&gt;workflows: multi user interactions, wait for X event to happen&lt;/li&gt;
&lt;li&gt;permissions: different set of groups for each every operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But also there is another space more related to the application on its own:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;configuration&lt;/li&gt;
&lt;li&gt;supervision&lt;/li&gt;
&lt;li&gt;reporting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is different from developpers and sysadmin work, it's more a &lt;em&gt;webmaster&lt;/em&gt;
work.&lt;/p&gt;
&lt;p&gt;Last but not least, «User features» stress the fact that this is related to
the user. So if a software wants to offer a framework for building an UI/UX
that can be further refined to deal with user matters, a specific business,
I think it must be expressed in the terms of users.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="code-feature"&gt;
&lt;h3&gt;Code feature&lt;/h3&gt;
&lt;p&gt;In what follows I try to gather all dos and doings of Django admin and also
what people would like to see in the admin. Except if you are interested
by the subject of customizing the admin you can skip it, it is used as a
reference for what follows.&lt;/p&gt;
&lt;p&gt;Have a look at &lt;a class="reference external" href="http://www.djangopackages.com/grids/g/admin-interface/"&gt;CMS&amp;#64;DjangoPackages&lt;/a&gt;.
Have a look at &lt;a class="reference external" href="http://www.djangopackages.com/grids/g/admin-interface/"&gt;AdminInterface&amp;#64;DjangoPackages&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="admin-apps"&gt;
&lt;h4&gt;Admin apps&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.grappelliproject.com/"&gt;Grappelli&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;Collapsibles&lt;/li&gt;
&lt;li&gt;Inline Sortables&lt;/li&gt;
&lt;li&gt;Sortable Excludes&lt;/li&gt;
&lt;li&gt;Related Lookups&lt;/li&gt;
&lt;li&gt;Autocomplete Lookups&lt;/li&gt;
&lt;li&gt;Using TinyMCE&lt;/li&gt;
&lt;li&gt;Changelist Templates&lt;/li&gt;
&lt;li&gt;Changelist Filters&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/jsocol/django-adminplus"&gt;django-adminplus&lt;/a&gt;, easily add custom views to the Django admin cf. #18665&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://bitbucket.org/izi/django-admin-tools/wiki/Home"&gt;django-admin-tools&lt;/a&gt;, see also &lt;a class="reference external" href="https://github.com/tswicegood/pops"&gt;pops&lt;/a&gt;.&lt;ul&gt;
&lt;li&gt;a full featured and customizable dashboard&lt;/li&gt;
&lt;li&gt;a customizable menu bar&lt;/li&gt;
&lt;li&gt;tools to make admin theming easier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/django-djam/django-djam"&gt;django-djam&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;Make it easy to add new workflows (or similar custom admin sections).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/disqus/nexus"&gt;nexus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="extensions"&gt;
&lt;h4&gt;Extensions&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/sehmaschine/django-filebrowser"&gt;Django FileBrowser&lt;/a&gt; media-management with Grappelli&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="git://github.com/liberation/django-massadmin.git"&gt;django-massadmin&lt;/a&gt; bulk edits&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/blancltd/django-mptt-treechangelist"&gt;django-mptt-treechangelist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/liberation/django-admin-tabs"&gt;django-admin-tabs&lt;/a&gt; tabs for model forms&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/amirouche/django-sneak"&gt;django-sneak&lt;/a&gt; custom objects in change list (filter and actions support)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/shaunsephton/django-ckeditor"&gt;django-ckeditor&lt;/a&gt; CKEditor integration&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/lukaszb/django-guardian"&gt;django-guardian&lt;/a&gt; implementation of per object permissions&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/bartTC/django-memcache-status"&gt;django-memcache-status&lt;/a&gt; displays statistics about your memcached instances&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/alex/django-admin-histograms"&gt;django-admin-histograms&lt;/a&gt; histograms&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/iambrandontaylor/django-admin-sortable"&gt;django-admin-sortable&lt;/a&gt; generic drag-and-drop ordering for objects and tabular inlines&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/jezdez/django-mobileadmin"&gt;django-mobileadmin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/runekaagaard/django-admin-filtrate"&gt;django-admin-filtrate&lt;/a&gt; custom filter framework&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="skins"&gt;
&lt;h4&gt;Skins&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://bitbucket.org/salvator/django-admintools-bootstrap"&gt;django-admintools-bootstrap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/divio/djangocms-admin-style"&gt;django-admin-style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/aobo711/bootstrap-django-admin"&gt;bootstrap-django-admin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/riccardo-forina/django-admin-bootstrapped"&gt;django-admin-bootstrapped&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/gkuhn1/django-admin-templates-twitter-bootstrap"&gt;django-admin-templates-twitter-bootstrap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/michaelhelmick/django-bootstrap-admin"&gt;django-bootstrap-admin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/AndrewIngram/django-extra-views"&gt;django-extra-views&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="other-interesting-app"&gt;
&lt;h4&gt;Other interesting app&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/bradleyayers/django-tables2"&gt;django-tables2&lt;/a&gt; build tables directly from queryset&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/etianen/django-reversion"&gt;django-reversion&lt;/a&gt; version control&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/jezdez/django-appconf"&gt;django-appconf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/liberation/django-dynamiq-search-form"&gt;django-dynamiq-search-form&lt;/a&gt; create dynamic search forms that generate Q objects.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/liberation/django-locking"&gt;django-locking&lt;/a&gt; it has admin integration&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/stephenmcd/django-forms-builder"&gt;django-forms-builder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/idlesign/django-sitetree"&gt;django-sitetree&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="feature-requests"&gt;
&lt;h4&gt;Feature requests&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;«system for administrators to be notified about specific model
instances about which they need to take action» in»
&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!searchin/django-developers/admin/django-developers/I4QtOx2HBH0/jaq_sJzpNWMJ"&gt;Admin notifications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From «&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!searchin/django-developers/admin/django-developers/jijI4rwjLkI/hjvqLAztnr4J"&gt;Call for ideas: Admin Improvements&lt;/a&gt;» 3/31/09, those are a bit old but &lt;em&gt;maybe&lt;/em&gt; still current:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ajax/UI/UX: Autocomplete widget, Drag &amp;amp; Drop, inplace edit&lt;/li&gt;
&lt;li&gt;Dynamic filters based on models&lt;/li&gt;
&lt;li&gt;Finer Permissions limit the ability of a user right down to the created object&lt;/li&gt;
&lt;li&gt;Dynamic add/remove columns for models&lt;/li&gt;
&lt;li&gt;Foreign Key filtering&lt;/li&gt;
&lt;li&gt;History improvements with undo functionality (this is already done with django-reversion but is an excellent addon)&lt;/li&gt;
&lt;li&gt;Mass file/photo upload&lt;/li&gt;
&lt;li&gt;Add and remove instances to/from formsets with a button&lt;/li&gt;
&lt;li&gt;Photo Management - crop, rotate (with ability to add more filters)&lt;/li&gt;
&lt;li&gt;Make it easier for people to create custom themes and styles for the admin and change between them&lt;/li&gt;
&lt;li&gt;Allow models to be added twice with two modeladmins serving a different process &lt;em&gt;this is possible with ModelProxy&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other topics:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;«&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!searchin/django-developers/admin/django-developers/aj1VEkA3FwI/pUxKQvb00cQJ"&gt;Admin Javascript Roadmap/Brainstorming&lt;/a&gt;» 11/28/12&lt;/li&gt;
&lt;li&gt;«&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!topic/django-developers/VPUdv2PSQtE"&gt;Splitting out admin functionality&lt;/a&gt;» 10/10/11&lt;/li&gt;
&lt;li&gt;«&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!topic/django-developers/Vozu6U3gz84"&gt;Django Admin Revamp - Any updates?&lt;/a&gt;»&lt;ul&gt;
&lt;li&gt;«admin is a contrib app for a reason -- it's a standalone app. It's entirely possible to recreate everything Django's admin does as a third party application. If a third party admin implementation were to appear that had a better feature set than the existing admin, and/or a better codebase to start from, and there was a reasonable migration path from old admin configurations to new admin configurations, &lt;em&gt;that&lt;/em&gt; might be a viable way to get a new admin into Django.» Russell Keith-Magee&lt;/li&gt;
&lt;li&gt;«Admin should be as forward-looking as the last version [of Grappelli], which means rethinking what the admin does, not just how it looks» Idan Gazit&lt;/li&gt;
&lt;li&gt;«Increasing the flexibility for development and integration is more important than trying to 2nd guess where we are going to be in 5 years time. » Brett H&lt;/li&gt;
&lt;li&gt;«This discussion could start with defining the so-called &amp;quot;trusted editor&amp;quot; – what does he/she knows resp. needs to know when dealing with the admin-interface? What are the consequences (e.g., does an editor care about an app-list, does he even know what it is)? What working-groups do we need (python, html/css, js, ...)?» patrickk&lt;/li&gt;
&lt;li&gt;«The problem with the external [boostrap integration] app approach is that it will break the integration between different apps. There is no way to avoid it.» Riccardo Forina&lt;/li&gt;
&lt;li&gt;«Secure CRUD one-liner goal» is_null&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;a class="reference external" href="https://code.djangoproject.com/query?status=assigned&amp;amp;status=new&amp;amp;component=contrib.admin&amp;amp;col=id&amp;amp;col=summary&amp;amp;col=component&amp;amp;col=status&amp;amp;col=owner&amp;amp;col=type&amp;amp;order=id"&gt;django trac&lt;/a&gt; I find those tickets interesting:&lt;/p&gt;
&lt;div class="section" id="hooks"&gt;
&lt;h5&gt;Hooks&lt;/h5&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Easily link up custom admin views to admin:index &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18665"&gt;#18665&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Include reverse()-able links and off site URLs to admin:index on a per app basis &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18665"&gt;#18665&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Object tool customization &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18914"&gt;#18914&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin Changelist: add app-model_name class to &amp;lt;body&amp;gt; tag &lt;a class="reference external" href="https://code.djangoproject.com/ticket/13629"&gt;#13629&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use short description with properties in the admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/17308"&gt;#17308&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add more hooks in the ModelAdmin (get_extra, get_max_num) &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18388"&gt;#18388&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Allowing inline fields to be specified in the fields tuple &lt;a class="reference external" href="https://code.djangoproject.com/ticket/4848"&gt;#4848&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Support nested fieldsets in administration &lt;a class="reference external" href="https://code.djangoproject.com/ticket/10590"&gt;#10590&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Support lookup separators in ModelAdmin.list_display &lt;a class="reference external" href="https://code.djangoproject.com/ticket/10743"&gt;#10743&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="ui-ux"&gt;
&lt;h5&gt;UI/UX&lt;/h5&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Add support for custom app_label and verbose_name» &lt;a class="reference external" href="https://code.djangoproject.com/ticket/3591"&gt;#3591&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Include blocks in admin:index to customize the displaying of each app block &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18665"&gt;#18665&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ability to define the sort order of the apps manually. &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18665"&gt;#18665&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Flexible filters for django admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18736"&gt;#18736&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add next/previous buttons when editing a model in the admin site &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18957"&gt;#18957&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin actions displayed as buttons instead of drop-down list &lt;a class="reference external" href="https://code.djangoproject.com/ticket/19235"&gt;#19235&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add option to disable Admin log (LogEntry) &lt;a class="reference external" href="https://code.djangoproject.com/ticket/19302"&gt;#19302&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Link to object in message after creating/updating object in django admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/19361"&gt;#19361&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SelectBox.js with grouping (optgroup elements) &lt;a class="reference external" href="https://code.djangoproject.com/ticket/13883"&gt;#13883&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Adding support for Autocomplete in contrib.admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/14370"&gt;#14370&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Model description on administrative interface &lt;a class="reference external" href="https://code.djangoproject.com/ticket/14587"&gt;#14587&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin search should be pluggable &lt;a class="reference external" href="https://code.djangoproject.com/ticket/15961"&gt;#15961&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Provide keyboard shortcuts in admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16521"&gt;#16521&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Improve multiple sort UX &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16212"&gt;#16212&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin history view should also show history of super-object(s) &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16465"&gt;#16465&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use short description with properties in the admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/17308"&gt;#17308&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Filtering interface on ForeignKey &amp;lt;select&amp;gt; boxes &lt;a class="reference external" href="https://code.djangoproject.com/ticket/25"&gt;#25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fix usability issue with limit_choices_to and &amp;quot;Add another&amp;quot; in admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/29"&gt;#29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Bi-Directional ManyToMany in Admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/897"&gt;#897&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Multi-select admin filter for RelatedFields &lt;a class="reference external" href="https://code.djangoproject.com/ticket/1873"&gt;#1873&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Adding to admin nice selector for editing ForeignKey fields in case of relatively large number of items &lt;a class="reference external" href="https://code.djangoproject.com/ticket/2651"&gt;#2651&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Better OneToOneField handling in Admin Interface desired &lt;a class="reference external" href="https://code.djangoproject.com/ticket/2948"&gt;#2948&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ability to disable admin pagination &lt;a class="reference external" href="https://code.djangoproject.com/ticket/4065"&gt;#4065&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Easier way to overwite the admin welcome message &lt;a class="reference external" href="https://code.djangoproject.com/ticket/7467"&gt;#7467&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ModelAdmin hook for customising the &amp;quot;show on site&amp;quot; button &lt;a class="reference external" href="https://code.djangoproject.com/ticket/8261"&gt;#8261&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Allow overriding of default adminsite. &lt;a class="reference external" href="https://code.djangoproject.com/ticket/8500"&gt;#8500&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Generic Foreign Keys should have a nice widget &lt;a class="reference external" href="https://code.djangoproject.com/ticket/9976"&gt;#9976&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Show admin actions on the edit pages too &lt;a class="reference external" href="https://code.djangoproject.com/ticket/12090"&gt;#12090&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;quot;Tooltips&amp;quot; in admin list view &lt;a class="reference external" href="https://code.djangoproject.com/ticket/12701"&gt;#12701&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add has_module_permission to ModelAdmin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/6327"&gt;#6327&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Year navigation in admin's date widgets' calendar &lt;a class="reference external" href="https://code.djangoproject.com/ticket/9388"&gt;#9388&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="other"&gt;
&lt;h5&gt;Other&lt;/h5&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Dogfood class-based views in contrib.admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/17208"&gt;#17208&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Logout link should be protected &lt;a class="reference external" href="https://code.djangoproject.com/ticket/15619"&gt;#15619&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;FilterSpec implementation limits querying functionality &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16142"&gt;#16142&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;View collections in the generic views &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16213"&gt;#16213&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Enable admin log display to be restricted to a specific site &lt;a class="reference external" href="https://code.djangoproject.com/ticket/2901"&gt;#2901&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Some admin Javascript cleanups &lt;a class="reference external" href="https://code.djangoproject.com/ticket/4045"&gt;#4045&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reusable templatetags for admin list &lt;a class="reference external" href="https://code.djangoproject.com/ticket/6159"&gt;#6159&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add databrowse-like functionality to the admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/8936"&gt;#8936&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Nested Inline Support in Admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/9025"&gt;#9025&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Some admin Javascript fixes and cleanups &lt;a class="reference external" href="https://code.djangoproject.com/ticket/4045"&gt;#4045&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add admin.site._registry manipulation methods &lt;a class="reference external" href="https://code.djangoproject.com/ticket/9602"&gt;#9602&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ModelAdmin.queryset() is missing a mechanism for specifying different querysets for changelist and change object views &lt;a class="reference external" href="https://code.djangoproject.com/ticket/10761"&gt;#10761&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin object deletion confirmation page causes server out of memory error &lt;a class="reference external" href="https://code.djangoproject.com/ticket/10919"&gt;#10919&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin action templates cannot be overriden on a per-app basis &lt;a class="reference external" href="https://code.djangoproject.com/ticket/12566"&gt;#12566&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Admin validation doesn't reflect ModelAdmin's extensibility &lt;a class="reference external" href="https://code.djangoproject.com/ticket/12674"&gt;#12674&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;API for simpler (permission or any) checks for generic view classes &lt;a class="reference external" href="https://code.djangoproject.com/ticket/15215"&gt;#15215&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Among many others.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="sum-up"&gt;
&lt;h3&gt;Sum up&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Permissions&lt;/strong&gt; django-guardian, #6327&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More object navigation and filtering&lt;/strong&gt; django-admin-filtrate, django-dynamiq-search-form, #18736, #18957, #19302, #25, #1873, #9388, #16142, #10761&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better support of complex data in ModelAdmin forms&lt;/strong&gt; django-admin-tabs, #10590, #897, #2651, #2948&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom objects in change list&lt;/strong&gt; Django-FileBrowser, django-mptt-treechangelsit, django-sneak, #9976&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Geneirc UX/UI, and ajax features&lt;/strong&gt; django-admin-sortable, edit inplace, #13883, #16521, #16212, #16212, #16465, #17308, #29, #4065, #7467, #12090, #12701&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More hooks and configuration&lt;/strong&gt; django-adminplus, #18665, #18914, #17308, #18388, #4848, #8261, #2901, #6159, #12566&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Customizable dashboard and menu bar&lt;/strong&gt; most CMS, grappelli, django-memcache-status, django-admin-tools&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="adminnext"&gt;
&lt;h2&gt;AdminNext&lt;/h2&gt;
&lt;p&gt;If you did not read the above basicaly that's what I took into account to come
up with an idea for AdminNext. I think that the most important tickets are the
following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Dogfood class-based views in contrib.admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/17208"&gt;#17208&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Making it easier to customize Django Admin &lt;a class="reference external" href="https://code.djangoproject.com/ticket/18665"&gt;#18665&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;View collections &lt;a class="reference external" href="https://code.djangoproject.com/ticket/16213"&gt;#16213&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;API for simpler (permission or any) checks for generic view classes &lt;a class="reference external" href="https://code.djangoproject.com/ticket/15215"&gt;#15215&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Talking about CBV, I just can't find the ticket but there is CBV that wants to
talk with several form. I like the idea but it breaks OOP principles.
Inheritance is «is a» relation, where composition, done through a property, is
«has a» relation, so which one sound better:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;ModelAdmin&lt;/tt&gt; has several forms&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;ModelAdmin&lt;/tt&gt; is a form aggregation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second sound akward and I tried my best not to use the word «composition».&lt;/p&gt;
&lt;p&gt;I should have probably entitled this paragraph «cbv-admin» but then it
wouldn't have been a surprise to say that it is an almost solved problem.
I say almost because it's quiet a bit of code but there is a lot of tests
to have it checked for both backward compatibility and progress.&lt;/p&gt;
&lt;p&gt;I also say almost because it's only supposed that CBV will solve the
extensibility problem, I personnaly have no hard evidence of that, except
maybe Mixins.&lt;/p&gt;
&lt;p&gt;What was proposed in &lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!topic/django-developers/VPUdv2PSQtE"&gt;Splitting out admin functionality&lt;/a&gt;
is really interesting too, but this will not benefit the admin, per se.&lt;/p&gt;
&lt;p&gt;The problem is that I try to tackle it bottom-up, instead of up-bottom.
Like I said ealier &lt;em&gt;code-feature vs. user-feature&lt;/em&gt;. The user doesn't care
about the feature of the code, he or she wants to talk in terms of &lt;em&gt;dos&lt;/em&gt;:
«I do that then I do this, then when X event, I do that, If Y do those».
A software doesn't speak this language, a language does, the framework
should be in between.&lt;/p&gt;
&lt;p&gt;At work, I had a problem, this was minor but I think it's symptomatic of
how the admin works and give a hint about what is wrong. We had two
applications, one of the applicatins works standalone but the other relate
to the first. A model for the latter had M2M relation to a model of the former.
The ChangeList refered to those via a count column. When you clicked on it,
you were suddenly &lt;em&gt;teleported&lt;/em&gt; to the filtered ChangeList of another model in
another application for further inspection. This is what is wrong, basically
the user is in a context then a different context with the possibility of
getting lost without hitting «back» browser button. You might have guessed
that what I find wrong is that the admin is model centric instead of procesus
centric. While I definitly need to read some &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Process"&gt;process&lt;/a&gt;
definitions, I think what match best the ideas behind it, is «groups», both
«groups of processus» and «groups of users». That's why I think AdminNext
should be &lt;strong&gt;groups centric&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;How ? I don't know yet but the admin certainly needs to me more pluggable
and customizable (aka. extensible), so what is above still holds. To make
the admin or its features pluggable those must be able to live outside of
the admin. When those components are pluggable would it make sens to ship
something that use it to implement something else than the admin which takes
some assumptions regarding application ergonomy that isn't default
in most applications ?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="where-do-i-go-from-here"&gt;
&lt;h2&gt;Where do I go from here ?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I'd like to know how does django-composite tackle the pluggability
of the elements of the admin. I'm pretty sure it does but I'd like to see
it.&lt;ul&gt;
&lt;li&gt;If I'm satisfied I'll propose the concept to be included in Django&lt;/li&gt;
&lt;li&gt;If not template tags will do.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Then, I'll do some Django bugs smashing :)&lt;/li&gt;
&lt;li&gt;I will also dive into admin backends and ergonomy to see what people do&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How can you help? Pick a subject that you are interested in and do something
with it. And like Russel Keith-Magee said «Look for the general problem, not
the specific. If you can solve the general problem, the net gain is much
larger.» [&lt;a class="reference external" href="https://groups.google.com/forum/?fromgroups=#!searchin/django-developers/admin/django-developers/I4QtOx2HBH0/jaq_sJzpNWMJ"&gt;django-developers&lt;/a&gt;]&lt;/p&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/XLMDfnSF31Y" height="1" width="1"/&gt;</summary><category term="code" /><category term="python" /><category term="django" /><feedburner:origLink>http://amirouche.github.com/blog/django-admin-next.html</feedburner:origLink></entry><entry><title>Meta framework: Part one</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/t6pPG_7QTO4/meta-framework-part-one.html" rel="alternate" /><updated>2013-01-01T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2013-01-01:meta-framework-part-one.html</id><summary type="html">&lt;div class="section" id="what"&gt;
&lt;h2&gt;What ?&lt;/h2&gt;
&lt;p&gt;This title sound obnoxious, each of the words taken
alone are already the source of a lot of flame wars. Guess what this
an already solved problem and it has Zope in its name!&lt;/p&gt;
&lt;p&gt;Maybe you read my &lt;a class="reference external" href="http://amirouche.github.com/blog/new-years-python-meme-2012.html"&gt;#2012pythonmeme&lt;/a&gt;
then you know that I would like a «a full stack framework
to do web, dekstop, mobile and &lt;a class="reference external" href="https://unhosted.org/"&gt;unhosted&lt;/a&gt; applications».
This is not just me surfing on top of the buzz several other
pythonista expressed similar wish. Moreover this kind of things
already exists, like &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Google_Web_Toolkit"&gt;GWT&lt;/a&gt;
and &lt;a class="reference external" href="http://pyjs.org/"&gt;pyjs&lt;/a&gt; (formely pyjamas), &lt;a class="reference external" href="http://www.meteor.com/"&gt;meteor&lt;/a&gt;
and probably others. In other families of software they are most kernels,
GUI toolkits and anything that deals with multi-plateform and has to deal
with the absence of standard or cross-standards or just backward compatibility.&lt;/p&gt;
&lt;p&gt;This is definitly a common pattern in software
developpement. Summaries of the following Structural
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Software_design_pattern#Domain-specific_patterns"&gt;design patterns&lt;/a&gt;
prooves that this very common:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Adapter&lt;/strong&gt; or &lt;strong&gt;Wrapper&lt;/strong&gt; or &lt;strong&gt;Translator&lt;/strong&gt;: Convert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces. The enterprise integration pattern equivalent is the translator&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bridge&lt;/strong&gt;: Decouple an abstraction from its implementation allowing the two to vary independent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facade&lt;/strong&gt;: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flyweight&lt;/strong&gt;: Use sharing to support large numbers of similar objects efficiently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module&lt;/strong&gt;: Group several related elements, such as classes, singletons, methods, globally used, into a single conceptual entity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy&lt;/strong&gt;: Provide a surrogate or placeholder for another object to control access to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other patterns that I think are related:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Abstract factory&lt;/strong&gt;: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mediator&lt;/strong&gt;: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strategy&lt;/strong&gt;: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don't only want to sound érudit, I back up my intentions with
proofs. So, this a doing and hence probably doable.&lt;/p&gt;
&lt;div class="section" id="framework-for-frameworks"&gt;
&lt;h3&gt;Framework for frameworks&lt;/h3&gt;
&lt;p&gt;What is meta-framework or framework for frameworks.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It's not related to meta-programming, per se, but can offer some facility to
ease the creation of APIs that use such programming technics pervasive in
application frameworks.&lt;/li&gt;
&lt;li&gt;It offers a canvas for creating pluggable applications&lt;/li&gt;
&lt;li&gt;It offers a canvas for creating extensible applications&lt;/li&gt;
&lt;li&gt;It can offer a canvas for programming&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="how"&gt;
&lt;h2&gt;How ?&lt;/h2&gt;
&lt;div class="section" id="solved-problem"&gt;
&lt;h3&gt;Solved problem&lt;/h3&gt;
&lt;p&gt;At least the meta-framework part or its base component is I think solved by
&lt;a class="reference external" href="http://www.muthukadan.net/docs/zca.html"&gt;Zope Component Architecture&lt;/a&gt;
(cf. &lt;a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/designdefense.html"&gt;Defending Pyramid’s Design&lt;/a&gt;),
even if it's not refered as «meta-framework».
But I think it is, since it offers what is needed to
plug and extend any &lt;em&gt;pieces&lt;/em&gt; in a software, thus the framework
would be to specify these &lt;em&gt;pieces&lt;/em&gt; and probably providing
default implementation which I think is the purpose of softwares
like &lt;a class="reference external" href="http://www.pylonsproject.org/"&gt;Pyramid&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I won't refer to ZCA any further to avoid any confusion.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="moar-solutions"&gt;
&lt;h3&gt;Moar solutions&lt;/h3&gt;
&lt;div class="section" id="callable-class"&gt;
&lt;h4&gt;Callable class&lt;/h4&gt;
&lt;div class="section" id="presentation"&gt;
&lt;h5&gt;Presentation&lt;/h5&gt;
&lt;p&gt;First I'm fascinated by callable class, I have no particular
interest or knowledge in functionnal programming, I just find them
beautiful. A callable class in Python is a class that defines a
&lt;tt class="docutils literal"&gt;__call__&lt;/tt&gt; method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CallMe&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;name&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;Héllo &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&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;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It used this way:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;call_me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CallMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;callable class&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;call_me&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="go"&gt;Héllo callable class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Neat isn't it ?&lt;/p&gt;
&lt;p&gt;Except the fact that you have to instantiate it first, it produce
code similar to function call but the function is configurable as such
a callable class can be seen as function factory. The above example is an
example of that. But it doesn't take «function arguments», let's correct this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CallMe&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;name&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&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;adj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;Héllo &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adj&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;name&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;__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="n"&gt;call_me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CallMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;configurable function&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;call_me&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will print &lt;tt class="docutils literal"&gt;Héllo awesome configurable function&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;This can also be achieved with a function, but you will have to
repeat for every call of &lt;tt class="docutils literal"&gt;call_me&lt;/tt&gt; the &lt;tt class="docutils literal"&gt;name&lt;/tt&gt; argument.&lt;/p&gt;
&lt;p&gt;Another pattern is to build the &lt;tt class="docutils literal"&gt;call_me&lt;/tt&gt; function from another
function:&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;call_me_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;call_me&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
         &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;Héllo &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&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;call_me&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works similarly to the above &lt;tt class="docutils literal"&gt;CallMe&lt;/tt&gt; class except it is less readable.&lt;/p&gt;
&lt;p&gt;Another pattern is the ability to factorize some inner working of
the callable in a method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CallMe&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&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;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate&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;msg&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;msg&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&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;adj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;hello&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;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;Héllo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&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;%s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;adj&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;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can be done for readability or because some function is recursive or
needs to be called several times the same function. But this can also
be achived without class just using a module and functions.&lt;/p&gt;
&lt;p&gt;Another interesting aspect is the fact it is a class, thus it can be subclassed
and its behaviour changed from outside:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BabelCallMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CallMe&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;translate&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;msg&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;babel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;translate&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;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, you still can use a factory function...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="callable-class-all-the-things"&gt;
&lt;h5&gt;Callable-class all the things&lt;/h5&gt;
&lt;p&gt;I'm not 100% sure this will work, but at least in my current experience
of Python developpement it's rare to mutate an object from outside,
most of the time you instantiate a class once or it is already
instantiated and use it then &lt;em&gt;bye&lt;/em&gt;. More over most of the time,
since you call the class only one time, the entry point is a method instead
of &lt;tt class="docutils literal"&gt;__call__&lt;/tt&gt; to allow for readable code. But it &lt;em&gt;should&lt;/em&gt; be possible
to name the class or class instance in a way that makes it obvious what
it does when it is called like a function. If a class has several purpose,
then it is possible to wrap it in another class so that each class
has only one method to call.&lt;/p&gt;
&lt;p&gt;In the case needs to have several call methods, it can the following pattern:&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;MethodDispatch&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="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method_one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CallableClass&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="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CallableClass&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;/pre&gt;&lt;/div&gt;
&lt;p&gt;So that when you want to use &lt;tt class="docutils literal"&gt;MethodDispatch&lt;/tt&gt;, you do the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;method_dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MethodDispatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;method_dispatch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method_one&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks like a regular method call but it isn't.&lt;/p&gt;
&lt;p&gt;While this might not be a good pattern, since it multiply the number of objects
and class, you can also use a dispatch argument when you call a callable object,
using a switch-like statement:&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;ArgumentDispatch&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;__call__&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;algorithm&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;algorithm&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;trolilol&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;trolilol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;algorithm&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;spam&amp;amp;egg inc.&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;spam_and_egg&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;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is kind of evil meta programming technics, that I've exposed here
for the sake of completness since in my vision the &lt;em&gt;end user&lt;/em&gt; should never
have to deal with dispatching directly, the meta-framework should deal
with this kind of things.&lt;/p&gt;
&lt;p&gt;The purpose of this is to avoid complicated classes that said it doesn't
mean that a class can't be complex, it can still have several methods but
those will be for internal use only.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="semantic-based-object-names"&gt;
&lt;h4&gt;Semantic based object names&lt;/h4&gt;
&lt;p&gt;In an application there is several components, the application
way to name the libraries its use is by their name, for
instance &lt;em&gt;SQLAlchemy&lt;/em&gt;, &lt;em&gt;PySide&lt;/em&gt; and &lt;em&gt;werkzeug&lt;/em&gt; which can be respectively
named &lt;em&gt;orm&lt;/em&gt;, &lt;em&gt;gui&lt;/em&gt; and &lt;em&gt;wsgi&lt;/em&gt; or &lt;em&gt;data&lt;/em&gt;, &lt;em&gt;ui&lt;/em&gt; and &lt;em&gt;gateway&lt;/em&gt; at the framework
level depending on the level of abstraction. So you deal with data this way:&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;framework.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Model&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;framework.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;framework.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;persistence&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;app&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stub&lt;/span&gt;&lt;span class="p"&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&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;creation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&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;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stub&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="s"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;I am going well and you ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;persistence&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build_from_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;db&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;hello&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;persistence.build_from_config&lt;/tt&gt; is vague at best and use a global variable
as configuration which is strictly forbidden! Configuration is the purpose of
the next section.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration"&gt;
&lt;h4&gt;Configuration&lt;/h4&gt;
&lt;p&gt;Configuration should be auto-discoverable, customizable and allow to override
the application inner working from outside.&lt;/p&gt;
&lt;p&gt;Auto-discoverable means that
given a context of execution it knows what it should do. For instance, given
a callable that takes a &lt;tt class="docutils literal"&gt;user&lt;/tt&gt; as argument, depending on the configuration
&lt;tt class="docutils literal"&gt;user.notify&lt;/tt&gt; will be implemented differently depending of the running
program:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;CLI based program will use &lt;tt class="docutils literal"&gt;print()&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Daemon-like programs can use OS logging facility or send a mail&lt;/li&gt;
&lt;li&gt;GUI based programs will rely on some widget&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="end"&gt;
&lt;h3&gt;End&lt;/h3&gt;
&lt;p&gt;This is the end! More meta-framework programming will come. I will try not
to document myself more about ZCA  and framework developpement so that
this keeps it primary purpose: an exercice of creativity and problem solving.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/t6pPG_7QTO4" height="1" width="1"/&gt;</summary><category term="code" /><category term="python" /><feedburner:origLink>http://amirouche.github.com/blog/meta-framework-part-one.html</feedburner:origLink></entry><entry><title>Colophon</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/iivkHiC2uVk/colophon.html" rel="alternate" /><updated>2012-12-30T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2012-12-30:colophon.html</id><summary type="html">&lt;p&gt;You can definitly have a look at the source, but since you are here you are
looking for more.&lt;/p&gt;
&lt;p&gt;This is an original theme by me for &lt;a class="reference external" href="http://blog.getpelican.com/"&gt;pelican&lt;/a&gt;,
built using:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://foundation.zurb.com/"&gt;foundation css framework&lt;/a&gt; to ease the pain and
learn the basics which are not very different from twitter bootstrap and for which
there is actually a
&lt;a class="reference external" href="http://foundation.zurb.com/docs/joyride.php"&gt;documentation&lt;/a&gt; with live
demos.&lt;/li&gt;
&lt;li&gt;The font used for the titles is the awesome open source
&lt;a class="reference external" href="https://github.com/theleagueof/league-gothic"&gt;League Gothic&lt;/a&gt;,
I used it for all &lt;a class="reference external" href="https://speakerdeck.com/amiramazig"&gt;my slides&lt;/a&gt; so far.&lt;/li&gt;
&lt;li&gt;I also use &lt;a class="reference external" href="https://github.com/daneden/animate.css"&gt;animate.css&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.frequency-decoder.com/demo/slabText/"&gt;slabText&lt;/a&gt; is used to
render the big titles&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://masonry.desandro.com/index.html"&gt;mansonry&lt;/a&gt; to render the index pages&lt;/li&gt;
&lt;li&gt;the background is from &lt;a class="reference external" href="http://subtlepatterns.com/"&gt;subtle patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And &lt;a class="reference external" href="https://github.com/amirouche/amirouche.github.com"&gt;github&lt;/a&gt; to host all the things.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Like Tupac says «Keep your head up!»&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/iivkHiC2uVk" height="1" width="1"/&gt;</summary><feedburner:origLink>http://amirouche.github.com/blog/colophon.html</feedburner:origLink></entry><entry><title>New Year's Python Meme 2012</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/xg-wQMdAta4/new-years-python-meme-2012.html" rel="alternate" /><updated>2012-12-30T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2012-12-30:new-years-python-meme-2012.html</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://blog.ziade.org/2012/12/23/new-years-python-meme-2012/"&gt;Tarek Ziadé&lt;/a&gt;
is doing a meme each year about Python, a good occasion to share.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. What’s the coolest Python application, framework or library you have discovered in 2012 ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It's hard to tell, since it's both my first year as a professionnal which also
happens to have been related to Python and Django to be precise and the first
year of me getting involved in the Python and FOSS community by contributing
code, actively trying to stay in the loop and blogging: I learned &lt;strong&gt;a lot&lt;/strong&gt;.
And thus discovered a lot of the Python eco-system. If the question was about
the most awesome techno I discovered this year it would have been
&lt;a class="reference external" href="https://twitter.com/search?q=%23graphdb&amp;amp;src=typd"&gt;graph databases&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I will list all the things I discovered this year in Python that I liked
very much and then I will try to choose one:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.zeromq.org/bindings:python"&gt;PyZMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/kivy/pyjnius"&gt;pyjnius&lt;/a&gt; I didn't knew about JNI,
hence didn't know one could call Java code from Python!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://code.google.com/p/appengine-ndb-experiment/"&gt;appengine-ndb-experiement&lt;/a&gt; code
is really interesting&lt;/li&gt;
&lt;li&gt;Django, even if I knew about it, I know it way better now&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will stop here because it's of course
&lt;a class="reference external" href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt; and it's indeed pretty cool.&lt;/p&gt;
&lt;p&gt;Since ZeroMQ is getting quite a bit of publicity, I will add that the
&lt;a class="reference external" href="http://docs.python.org/2/library/multiprocessing.html"&gt;multiprocessing module&lt;/a&gt;
is pretty cool and that it can be used when you only need to communicate
over a network without all the patterns that ZeroMQ offers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. What new programming technique did you learn in 2012?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don't know if it's a programming technique but it's a pratical sens of what
I knew about Python to build APIs, like «here let's use a class property
since it's shared by all class» or that we can actually avoid declarative syntax
to achieve a similar purpose without meta-classes.&lt;/p&gt;
&lt;p&gt;I don't understand it fully yet but
&lt;a class="reference external" href="http://www.muthukadan.net/docs/zca.html"&gt;Zope Component Architecture&lt;/a&gt;
is an impressive software by its features, it changed the way I think about
extensibility and plugability making them a bit «automatic» and a bit magical
too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Which open source project did you contribute to the most in 2012? What did you do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Except Django for which I created several open source generic applications at
work and my own projects, &lt;a class="reference external" href="https://github.com/kivy/pyjnius"&gt;pyjnius&lt;/a&gt;.
Actually &lt;a class="reference external" href="http://cython.org/"&gt;Cython&lt;/a&gt; is not difficult, even if I have to
consider to create Python bindings of a C library in the future I will
probably use &lt;a class="reference external" href="http://cffi.readthedocs.org/en/latest/"&gt;cffi&lt;/a&gt; which is
supported by &lt;a class="reference external" href="http://pypy.org/"&gt;PyPy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Talking about pyjnius I find the
&lt;a class="reference external" href="https://github.com/kivy/pyjnius/blob/master/jnius/jnius_export_class.pxi#L184"&gt;Java method call resolution&lt;/a&gt;
quite interesting since it overrides the default Python method resolution which
does not support what I think is called method polymorphism.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. What was the Python blog or website you read the most in 2012?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don't read specific Python blog and website, most of my readings
comes from &lt;a class="reference external" href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt; even if I am
quite desappointed so I'm looking for something else.&lt;/p&gt;
&lt;p&gt;Regarding Python it is &lt;a class="reference external" href="http://www.cafepy.com/article/"&gt;cafepy&lt;/a&gt;
that I used as a reference to understand Python type/class system,
metaclasses and descriptors while coding
&lt;a class="reference external" href="https://bitbucket.org/amirouche/graphiti"&gt;Graphiti&lt;/a&gt;
and &lt;a class="reference external" href="https://bitbucket.org/amirouche/subscript"&gt;Subscript&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. What are the three top things you want to learn in 2013?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hu! That is a though question since there are too many.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It's not about learning and more about doing: better commits,
and release code that actually work in one time. It basicaly boils
down to be more rigourous and most importantly being &lt;strong&gt;patient&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Learn actual machine learning and probably learn some Math
along the way with &lt;a class="reference external" href="http://scikit-learn.org/stable/"&gt;scikit.learn&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learn or do more frontend developpement
&lt;a class="reference external" href="http://brython.info/"&gt;probably in Python&lt;/a&gt; but also in javascript.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;6. What is the top software, application or library you wish someone would write in 2013?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Maybe those already exists and maybe those are quite non-sensical or impossible
but here is the full list of softwares I wish existed all in Python except
otherwise noted and the last one can be in any language:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;a desktop environnement probably in Kivy and espeacially a browser&lt;/li&gt;
&lt;li&gt;a (meta) web app that will allow me to a) keep my data near b) that I can hack
d) enjoy freedom.&lt;/li&gt;
&lt;li&gt;A graph database, probably in Go, that can run Python queries cf.
&lt;a class="reference external" href="https://github.com/Printemps"&gt;PrintempsDB&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;an integrated (web?) developpement environnement so that I can learn,
improve my skills and ask for feedback all in one place.&lt;/li&gt;
&lt;li&gt;a full stack framework to do web, dekstop, mobile and
&lt;a class="reference external" href="https://unhosted.org/"&gt;unhosted&lt;/a&gt; applications&lt;/li&gt;
&lt;li&gt;Javascript in the browser, it's looks like &lt;a class="reference external" href="http://brython.info"&gt;brython&lt;/a&gt;
is solving that.&lt;/li&gt;
&lt;li&gt;A psychohistoir machine so that I can learn how to bring world peace
and inter galatic space missions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Like Bob Marley says «Time will tell» ;)&lt;/p&gt;
&lt;div class="section" id="want-to-do-your-own-list"&gt;
&lt;h2&gt;Want to do your own list ?&lt;/h2&gt;
&lt;p&gt;Here's how:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Copy-paste the questions and answer to them in your blog&lt;/li&gt;
&lt;li&gt;Tweet it with the &lt;a class="reference external" href="https://twitter.com/search/realtime?q=%232012pythonmeme&amp;amp;src=typd"&gt;#2012pythonmeme&lt;/a&gt; hashtag&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/xg-wQMdAta4" height="1" width="1"/&gt;</summary><category term="python" /><feedburner:origLink>http://amirouche.github.com/blog/new-years-python-meme-2012.html</feedburner:origLink></entry><entry><title>Nouveau Premier</title><link href="http://feedproxy.google.com/~r/protractileaigu/~3/w2TpeyidF0I/nouveau-premier.html" rel="alternate" /><updated>2012-12-29T00:00:00+01:00</updated><author><name>Amirouche</name></author><id>tag:amirouche.github.com/blog,2012-12-29:nouveau-premier.html</id><summary type="html">&lt;p&gt;Héllo! C'est Amirouche à l'autre bout du clavier de l'autre coté
de l'écran qui vous présente son nouveau blog.&lt;/p&gt;
&lt;p&gt;Je suis lasse de blogspot et de son editeur tout-pourri où il est difficile
d'intégrer des bouts de code. En fait je suis resté pour le thème, les poissons
et les envoies par mails qui me semblaient indispensables... Pas de miracle et
c'est bien avec des articles interessants et originaux qu'on arrive à toucher,
même si ils ne commentent pas, ça fait monter le kikimeter, flatte l'égo même
si par ailleurs déprime. Apparement c'est comme ça et pas autrement, je l'ai
accepté. Ceci dit philosophiquement c'était un peu dure de ne pas avoir
un système de commentaire sur un blog donc il y a un de nouveau sur celui-ci.&lt;/p&gt;
&lt;p&gt;Donc voilà ma nouvelle maison, un nouveau thème, un presque nouveau nom, une
nouvelle formule et surement pleins d'articles et peut être du code, j'espère
que ça vous plaira.&lt;/p&gt;
&lt;p&gt;J'ai un peu honte de n'avoir jamais fini aucune solution de publication qui
me satisfasse mais tanpis cela me donnera peut-être l'occasion de contribuer
à &lt;a class="reference external" href="http://blog.getpelican.com/"&gt;pelican&lt;/a&gt;, une solution de blogue qui jusqu'à
maintenant me satisfait dans un contexte technique original et cocasse pour les
fonctions que je veux ajouter.&lt;/p&gt;
&lt;p&gt;Si vous ne me connaissez pas c'est pas grave, «watchez» le dépôt sur
&lt;a class="reference external" href="https://github.com/amirouche/amirouche.github.com"&gt;github&lt;/a&gt; ou abonnez-vous
au flux et bientôt vous me connaitrez mieux.&lt;/p&gt;
&lt;p&gt;Porter les billets de l'&lt;a class="reference external" href="http://protractileaigu.blogspot.fr/"&gt;ancien blog&lt;/a&gt;
n'est pas prioritaire, il y a quelques brouillons que je veux publier avant.&lt;/p&gt;
&lt;p&gt;Aux portes de l'année 2013, j'ai pleins de nouveaux projets et d'opportunités
qui se presentent, encore pleins de choses que j'aimerai faire, mais stop au
teasing, comme dirait Oxmo Puccino «Tu déconnes avec tes tonnes de projets, ils
vont encore s'entasser avec ceux de l'année prochaine»...&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/protractileaigu/~4/w2TpeyidF0I" height="1" width="1"/&gt;</summary><category term="meta" /><feedburner:origLink>http://amirouche.github.com/blog/nouveau-premier.html</feedburner:origLink></entry></feed>
