<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>a Display of Patience</title>
	<atom:link href="http://www.displayofpatience.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.displayofpatience.net</link>
	<description>my favorite patient</description>
	<lastBuildDate>Thu, 29 Oct 2009 07:06:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Reading ajax content programmatically</title>
		<link>http://www.displayofpatience.net/2009/10/reading-ajax-content-programmatically/</link>
		<comments>http://www.displayofpatience.net/2009/10/reading-ajax-content-programmatically/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 21:44:47 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[PyQt4]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=196</guid>
		<description><![CDATA[Javascript and dynamic content loading with Ajax has changed the way web is being used. User interfaces have advanced rapidly and the &#8220;web content&#8221; is becoming more and more complex. This, however, presents whole new kinds of problems for parties other than the expected end user. Web content is intended to be read with a [...]]]></description>
			<content:encoded><![CDATA[<p>Javascript and dynamic content loading with Ajax has changed the way web is being used. User interfaces have advanced rapidly and the &#8220;web content&#8221; is becoming more and more complex. This, however, presents whole new kinds of problems for parties other than the expected end user. Web content is intended to be read with a graphical browser, such as Firefox or Google Chrome. Javascript capabilities are taken for granded, as they should, as we live in the modern ages <img src='http://www.displayofpatience.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  However, sometimes there still is a need for reading the content programmatically. Ajax content loading can become quite a pain in the ass in such situations, as I now have learnt.</p>
<p>In most cases, content retrieved by Ajax after the normal page is being loaded, isn&#8217;t a problem. If you really need the content, you can usually see how the Ajax call is made and use the same url for getting the data directly. In Most Cases. Sometimes the Ajax calls are not so obvious; the javascript might be obfuscated or you can&#8217;t really tell where the data is being loaded from. Or sometimes you just need to simulate the actual page loading. Test automation could be one of such situation. None the less, the problem is loading the actual data. Before Ajax-times, you could just use wget, or maybe a library provided by your programming language of choice (Python &#8211; urllib2) &#8211; to fetch the HTML source. Javascript changed this, as almost nothing, except the actual web browers, can execute it while reading the source.</p>
<p>Few days ago I faced such a problem. I spent most of my day figuring out how to read Javascript-rich web 2.0 page content using only tools available in shell environment. I preferred something I could use with Python, but nothing seemed to work. As I had almost lost all hope of achieving my goal, I decided to take one last look of PyQt4. I knew QT had a webkit component but I didn&#8217;t know if it can be used in a non graphical environemnt or if PyQt4 supported it. It can but it cannot and it does but it does not&#8230;</p>
<p>When I first tried PyQt4 it seemed to include WebKit module. But it didn&#8217;t. After a long session of banging my head against the wall I realized that even though the module QtWebKit was there, it didn&#8217;t actually do anything. It just failed silently when I used it. Then I came across this: <a href="http://www.insecure.ws/2008/09/16/xserver-less-webpage-screenshot#comment-239">http://www.insecure.ws/2008/09/16/xserver-less-webpage-screenshot#comment-239</a>. It seems version 4.4.2 of PyQt4 is sometimes build without support of WebKit. Guess which version I was using? I updated my PyQt and got immediately some results.  I also found out that QWebPage can be used in a widgetless situation. I also learnt that PyQt crashes when you create such object without first starting QtGui app by: QtGui.QApplication(sys.argv). It doesn&#8217;t work if you pass the second argument as False, for starting a non-Gui QT application. This seemed like a deal breaker to me, even though I was able to render the complex html with ajax calls just correctly with all the data included. It bugged the hell out of me. I drew no windows, no dialogs, nothing graphical. And yes, you cannot run a PyQt GUI application in shell, even though it produces no graphics. There was no physical QWebPage to be seen, everything happened on the background, why the hell it didn&#8217;t work as non Gui Qt Application? I never found an answer for this, but I found a way around it: XVFB, thanks to <a href="http://www.insecure.ws/2008/09/16/xserver-less-webpage-screenshot">the post</a> I referenced earlier.</p>
<p>Xvfb is a Virtual Framebuffer for X. What a life saver. I don&#8217;t know how it does it what it does, but basically it fakes a Display in linux environment where X is not available. I guess it directs everything to /dev/null or something, which in my case was just perfect, as I didn&#8217;t even want to produce anything graphical. My only interest was the HTML content, in textual format. So now, with the help of Xvfb, I can run &#8220;graphical programs&#8221; in shell and render my complex web pages programmatically, and parse the results as I please. Maybe my solution is not perfect and maybe there is some cleaner way of doing it, but I couldn&#8217;t find it. If you know, please share! Until that, I&#8217;m quite happy running my PyQt application (even though it seems to be quite heavy for such a basic task).</p>
<p>After I gave PyQt a shot, I did some googling and found out that others have used the same approach as me. Here&#8217;s one link:</p>
<p><a href="http://aezell.wordpress.com/2009/02/13/screenshot-a-url-with-python-and-qt-and-webkit/">http://aezell.wordpress.com/2009/02/13/screenshot-a-url-with-python-and-qt-and-webkit/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/10/reading-ajax-content-programmatically/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Simple example of Django on shared host</title>
		<link>http://www.displayofpatience.net/2009/10/simple-example-of-django-on-shared-host/</link>
		<comments>http://www.displayofpatience.net/2009/10/simple-example-of-django-on-shared-host/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 18:57:39 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=192</guid>
		<description><![CDATA[Displayofpatience.net runs on a shared host. It&#8217;s basically your avarage wordpress site, and the whole domain is dedicated to it. In addition to wordpress, I wanted to try if I could run a django site along with it. The first thing was to install Django.
Running stuff on a shared host can be tricky. Installing stuff [...]]]></description>
			<content:encoded><![CDATA[<p>Displayofpatience.net runs on a shared host. It&#8217;s basically your avarage wordpress site, and the whole domain is dedicated to it. In addition to wordpress, I wanted to try if I could run a django site along with it. The first thing was to install Django.</p>
<p>Running stuff on a shared host can be tricky. Installing stuff can be even trickier. My first task was to install Django. Even though my host/webhotel provided Django, I wanted to use a newer version. After digging around I found a wonderful little script for creating a virtual environemnt for Python. It basically creates bin &amp; lib (&amp; site-packages) directories to your home directory and links them to the system-wide python. Only now when you use your &#8220;local&#8221; python you can safely install stuff to the site-packages directory, using basic &#8220;setup.py install&#8221; method. It works great and you need no additional priviledges as you install everything under your home directory. Pretty cool. <a href="http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python">Check out more information about virtual-python here</a>.</p>
<p>After installing Django I was ready to try to set up a live site using it. I didn&#8217;t have any real needs for my Django site, so I decided to just hack something up, that demonstrates that I can use Django on my shared host. Displayofpatience.net runs on Apache, so I figured fcgi was the way to go. I created a .fcgi script according Django documentation and it worked out of the box. I, of course, used my own &#8220;local&#8221; python for running the fcgi script. Then I just configured  .htaccess file to handle .fcgi files (all in the Django docs). Django takes care from that on, according to the project urls.py.</p>
<p><a href="http://www.displayofpatience.net/django.fcgi/lotto/">Here is the outcome: The awesome Lottery machine!</a></p>
<p>To spice things up a little, I also added some JQuery ajax and animations to my program.  I hadn&#8217;t tried JQuery before, so that too was also a nice learning experience. I&#8217;m really happy about the outcome. Of course, the actual program is pretty useless, but now I can run my wordpress site as usually and Django applications along with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/10/simple-example-of-django-on-shared-host/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Scaler frontend</title>
		<link>http://www.displayofpatience.net/2009/08/scaler-frontend/</link>
		<comments>http://www.displayofpatience.net/2009/08/scaler-frontend/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 13:59:04 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ps3]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=157</guid>
		<description><![CDATA[In my previous ps3 post I tinkered with spe-scaler, which is a very nice tool to help you (for example) play emulator games in fullscreen. Unfortunately, it&#8217;s not very userfriendly, and I decided to write a little frontend program for it, to act as a gui. I first thought about writing it in QT/C++, but [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous ps3 post I tinkered with spe-scaler, which is a very nice tool to help you (for example) play emulator games in fullscreen. Unfortunately, it&#8217;s not very userfriendly, and I decided to write a little frontend program for it, to act as a gui. I first thought about writing it in QT/C++, but as I&#8217;m not that familiar with QT, I decided to do it in Python due time constraints. I chose Tkinter as a framework, which also was new to me, but as the program doesn&#8217;t do much I got it working pretty fast. Anyway, let me know what you think about it: <a href="http://www.displayofpatience.net/projects/scalergui/">scalergui</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/08/scaler-frontend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing emulator games with my ps3 with linux pt. 3 &#8211; scaler</title>
		<link>http://www.displayofpatience.net/2009/07/emulator-games-ps3-linux-scaler/</link>
		<comments>http://www.displayofpatience.net/2009/07/emulator-games-ps3-linux-scaler/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 09:29:34 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[emulator]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ps3]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=137</guid>
		<description><![CDATA[This is a follow up on my earlier posts of playing emulator games on ps3 with linux&#8230; (pt. 1, pt. 2)
As I said earlier, I wanted to do a clean install with the brand new Yellow Dog Linux 6.2 and that&#8217;s what I did. The installation wen&#8217;t fine, same as usual, and it took forever. [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a follow up on my earlier posts of playing emulator games on ps3 with linux&#8230; (<a href="http://www.displayofpatience.net/2008/10/playing-emulator-games-with-my-ps3-with-linux/">pt. 1</a>, <a href="http://www.displayofpatience.net/2008/10/playing-emulator-games-with-ps3-with-ydl/">pt. 2</a></em>)</p>
<p>As I said earlier, I wanted to do a clean install with the brand new Yellow Dog Linux 6.2 and that&#8217;s what I did. The installation wen&#8217;t fine, same as usual, and it took forever. Suprisingly the display was set correctly to 720p without any manual tweaking. At the time I thought it would be the ideal resolution for playing emulator games (from my earlier experiences).  There were narrow black borders around the screen, but I can live with that. So the next step, once again, was to install the actual emulators.</p>
<p>I added the <a href="http://pleasantfiction.ipower.com/bodega/viewtopic.php?f=6&amp;t=21&amp;start=0">PS3Bodega repos</a> as usual and installed following emulators: xe, vice and e-uae. At the time I did this, the YDL 6.2 repos were still missing content, so I had to manually add the dvd as a repository source (there were <a href="http://www.yellowdog-board.com/viewtopic.php?f=19&amp;t=3463&amp;sid=6632c458a3d12167ec8ad06f4db2bd7e">instructions</a> on the YDL forums for that), but it should only be a temporary problem and not needed in the future. Also, the bluetooth is not currently working in YDL 6.2, but I hope that too will be fixed soon. With the bluetooth not working, you have to use a usb cord for plugging in your controller, but luckily that works out of the box.</p>
<p>All the emulators I tried worked just about the same as before. I knew I couldn&#8217;t run most of the them in full screen, because the fps would drop dramatically. Instead I wanted to try the scaling method. With scaling, you run the emulators at their native resolution, which is usually very low. This way the fps should be fine. The <a href="http://blogs.ydl.net/billb/2008/07/16/zooma-zoom-zoom-and-a-doom-doom/">scaler</a> is an external program, which is developed for the CELL processor, and it uses the additional SPE&#8217;s to do all the work. The main CPU (PPE), which is running the emulator and the operating system, is not stressed. In other words the scaler program magnifies part of the screen, so you can get a bigger picture without using the emulators full screen or double screen actions, which would stress the main cpu and make the fps drop. The scaling method works quite well, but unfortunately it&#8217;s not very user friendly.</p>
<h2>Scaler</h2>
<p>To install the scaler, as root, do:</p>
<pre>yum install scaler</pre>
<p>Scaler is the original scaler program, but there are some modifications available, like f-scaler, which provides some additional features. Scaler is a command-line program which takes two arguments: -s and -t. &#8220;s&#8221; is for the scale, it has to be an interger, usually something between 2 and 4. The &#8220;t&#8221; is for timeout, I usually set it far (like 100000) and kill the process manually. This is how I use the scaler:</p>
<ol>
<li>Start the emulator just as usual and load up the game you want to play</li>
<li>Open terminal and start the scaler: &#8220;scaler -t 10000 -s 2&#8243;</li>
<li>-&gt; The display should now be scaled in the middle of the screen</li>
<li>Press alt-tab to switch to the emulator game</li>
<li>Use alt-mousedrag to center the window so you can see the whole screen.</li>
<li>Play</li>
<li>When finished, alt-tab change back to terminal and ctrl-c to kill the scaler process</li>
</ol>
<p>Not very userfriendly as you can see&#8230;</p>
<p>You probably might want to try the different scale options of the scaler for each emulator. Unfortunately you have to use integers, which makes it a somewhat limited tool. You cannot give the scaler an option like -s 1.5. I also figured that 720p is not very ideal for screen resolution, when using scaler, because anything over scale option 2 usually gets too big. So I changed my resolution to 1080p to get me more leverage when using the scaler. As you&#8217;re not using the emulator to get full screen, it runs perfectly ok, even if the reolution is so big. With vice for example, I use the scale option 4.</p>
<p>You can also start the scaler along with the emulator or create a script for it. You do it like this: &#8220;scaler -t 10000 -s 2 &amp; x64 &amp;&amp; killall scaler&#8221;. So that would first run the scaler, then the emulator x64 (vice) and afterwards when you quit the emulator it would also kill the scaler. I found this to be quite unusable, as you need menus to load up the games etc, but if you can or want to load the game using command line options of your emulator, it might be good way to go. I think people use that when playing mame games for example.</p>
<h2>Afterthoughts</h2>
<p>So using the scaler in my opinion is currently the best way to play emulator games in (almost) fullscreen. It&#8217;s not as easy and userfriendly as I&#8217;d hope it to be, but considering the alternatives, well, it&#8217;s basically the only way. Scaler is very helpful as it is, but I would like to see following features in the future:</p>
<ul>
<li>A Graphical User Interface. Would make it a lot easier to use for newbies</li>
<li>More scale options, not only integers. At least &#8220;half modes&#8221; like 2.5 needed.</li>
<li>The scaler could automatically get the target window size and calculate the optimal scaling to reach fullscreen (dynamic scaling)</li>
<li>Interactive scaling through hot-keys (like Ctrl+ would increase the scale and Ctrl- decrease)</li>
</ul>
<p>I know those features will most probably never be implemented but one can always wish right?</p>
<p>EDIT: Implemented <a href="http://www.displayofpatience.net/projects/scalergui/">Scalergui</a>. Check it out!</p>
<p>And here&#8217;s a little tip for those who want to use the xe multisystem emulator. It&#8217;s from <a href="http://www.yellowdog-board.com/viewtopic.php?f=19&amp;t=3171&amp;sid=6632c458a3d12167ec8ad06f4db2bd7e&amp;start=165#p30724">YDL forum.</a> I had some trouble when I wanted to use the controller to play games, but replacing these options to the configuration file(s) helped (~/.xe/rc/xerc):</p>
<pre># Joystick bindings

Joy     1       up              4
Joy     1       down            6
Joy     1       left            7
Joy     1       right           5
Joy     1       start           3
Joy     1       select          0
Joy     1       button1         15
Joy     1       button2         12
Joy     1       button3         14
Joy     1       button4         13</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/07/emulator-games-ps3-linux-scaler/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Going to try out ps3 YDL 6.2 soon</title>
		<link>http://www.displayofpatience.net/2009/07/going-to-try-out-ps3-ydl-6-2-soon/</link>
		<comments>http://www.displayofpatience.net/2009/07/going-to-try-out-ps3-ydl-6-2-soon/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 07:01:33 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[emulator]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ps3]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=135</guid>
		<description><![CDATA[It&#8217;s been a while since I last played around with my ps3 and linux and I thought I&#8217;d try out the latest version of Yellow Dog Linux (6.2). The goal is the same as in my previous posts: emulator games (megadrive, c64, amiga). What I have learned from past experiences is that I should probably [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I last played around with my ps3 and linux and I thought I&#8217;d try out the latest version of Yellow Dog Linux (6.2). The goal is the same as in my previous posts: emulator games (megadrive, c64, amiga). What I have learned from past experiences is that I should probably set the display straight to way to 720p, and forget about the fullscreen options found within the emulator software. Instead I should concentrate on how to use scalers specifically developed to take advantage of ps3 features (additional spu&#8217;s). Scalers are external programs that will magnify a part of the screen and they might be the way to play games in fullscreen. The trick is that they don&#8217;t use the main cpu, but the additional spe&#8217;s so the framerate shouldn&#8217;t drop. Last time I had some problems using them (they worked, but it was a pain to set them up for different emulators each time you wanted a play a game). It will be fun to see if there has been any development on that area.</p>
<p>I&#8217;m still going for YDL, since they have made some additional tweaks concerning ps3, that I&#8217;d have to do manually if using other distributions such as Ubuntu. There should be some VRAM swap tricks etc. I&#8217;m planning to do a clean install and I&#8217;m actually downloading the iso as I&#8217;m writing this. I hope I find the time to tinker with this soon and write about my latest experiences. So, hold on for &#8220;playing emulator games with my ps3 with linux pt. 3&#8243; <img src='http://www.displayofpatience.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/07/going-to-try-out-ps3-ydl-6-2-soon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django 1.0 Website Development by Ayman Hourieh -preview</title>
		<link>http://www.displayofpatience.net/2009/04/django-10-website-development-by-ayman-hourieh-preview/</link>
		<comments>http://www.displayofpatience.net/2009/04/django-10-website-development-by-ayman-hourieh-preview/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 13:45:57 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=106</guid>
		<description><![CDATA[The following is an extract from the recently published book &#8220;Django 1.0 Website Development&#8221; by Ayman Hourieh. I haven&#8217;t read it yet, but I&#8217;ll be writing a review as soon as I get my hands on it. The example covers basics of developing Django applications, and it should be a nice read for those unfamiliar [...]]]></description>
			<content:encoded><![CDATA[<p><em>The following is an extract from the recently published book </em><em>&#8220;<a href="http://www.packtpub.com/django-1-0-website-development-2nd-edition/book" target="_blank">Django 1.0 Website Development</a>&#8221; by<strong> Ayman Hourieh</strong>. I haven&#8217;t read it yet, but I&#8217;ll be writing a review as soon as I get my hands on it. The example covers basics of developing Django applications, and it should be a nice read for those unfamiliar with Django. I think it also gives you a good idea what the whole book is going to be like.  Anyway, the following is a (slightly formatted) copy/paste from the Packt Publishing website. There are also few other extracts available there. </em></p>
<h1>Building Friend Networks with Django 1.0</h1>
<p>Running a social web application means having a community of users who have common interests, and who use the application to share their interests and findings with each other. We will want to enhance the social experience of our users.</p>
<p>An important aspect of socializing in our application is letting users to maintain their friend lists and browse through the bookmarks of their friends. So, in this section we will build a data model to maintain user relationships, and then program two views to enable users to manage their friends and browse their friends&#8217; bookmarks.</p>
<h1>Creating the friendship data model</h1>
<p>Let&#8217;s start with the data model for the friends feature. When a user adds another user as a friend, we need to maintain both users in one object. Therefore, the <em>Friendship</em> data model will consist of two references to the <em>User</em> objects involved in the friendship. Create this model by opening the <em>bookmarks/models.py</em> file and inserting the following code in it:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Friendship<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
  from_friend = models.<span style="color: black;">ForeignKey</span><span style="color: black;">&#40;</span>User, related_name=<span style="color: #483d8b;">'friend_set'</span><span style="color: black;">&#41;</span>
  to_friend = models.<span style="color: black;">ForeignKey</span><span style="color: black;">&#40;</span>User, related_name=<span style="color: #483d8b;">'to_friend_set'</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> u<span style="color: #483d8b;">'%s, %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">from_friend</span>.<span style="color: black;">username</span>, <span style="color: #008000;">self</span>.<span style="color: black;">to_friend</span>.<span style="color: black;">username</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">class</span> Meta:
    unique_together = <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'to_friend'</span>, <span style="color: #483d8b;">'from_friend'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#41;</span></pre></div></div>

<p>The Friendship data model starts with defining two fields that are <em>User</em> objects: <em>from_friend</em> and <em>to_friend</em>. <em>from_friend</em> is the user who added <em>to_friend</em> as a friend. As you can see, we passed a keyword argument called <em>related_name</em> to both the fields. The reason for this is that both fields are foreign keys that refer back to the <em>User</em> data model. This will cause Django to try to create two attributes called <em>friendship_set</em> in each <em>User</em> object, which would result in a name conflict. To avoid this problem, we provide a specific name for each attribute. Consequently, each <em>User</em> object will contain two new attributes:<em> user.friend_set</em>, which contains the friends of this user and <em>user.to_friend_set</em>, which contains the users who added this user as a friend. Throughout this article, we will only use the <em>friend_set</em> attribute, but the other one is there in case you need it .</p>
<p>Next, we defined a <em>__unicode__</em> method in our data model. This method is useful for debugging.</p>
<p>Finally, we defined a class called <em>Meta</em>. This class may be used to specify various options related to the data model. Some of the commonly used options are:</p>
<ul>
<li><em>db_table</em>: This is the name of the table to use for the model. This is useful when the table name generated by Django is a reserved keyword in SQL, or when you want to avoid conflicts if a table with the same name already exists in the database.</li>
<li><em>ordering</em>: This is a list of field names. It declares how objects are ordered when retrieving a list of objects. A column name may be preceded by a minus sign to change the sorting order from ascending to descending.</li>
<li><em>permissions</em>: This lets you declare custom permissions for the data model in addition to add, change, and <em>delete</em> permissions. Permissions should be a list of two-tuples, where each two-tuple should consist of a permission codename and a human-readable name for that permission. For example, you can define a new permission for listing friend bookmarks by using the following <em>Meta</em> class:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Meta:
  permissions = <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'can_list_friend_bookmarks'</span>, <span style="color: #483d8b;">'Can list friend bookmarks'</span><span style="color: black;">&#41;</span>,<span style="color: black;">&#41;</span></pre></div></div>

</li>
<li><em>unique_together</em>: A list of field names that must be unique together.</li>
</ul>
<p>We used the <em>unique_together</em> option here to ensure that a <em>Friendship</em> object is added only once for a particular relationship. There cannot be two <em>Friendship</em> objects with equal <em>to_friend</em> and <em>from_friend</em> fields. This is equivalent to the following SQL declaration:</p>
<pre style="margin-left: 40px;">UNIQUE ("from_friend", "to_friend")</pre>
<p>If you check the SQL generated by Django for this model, you will find something similar to this in the code.</p>
<p>After entering the data model code into the <em>bookmarks/models.py</em> file, run the following command to create its corresponding table in the database:</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">$ python manage.py syncdb</span></pre>
<p>Now let&#8217;s experiment with the new model and see how to store and retrieve relations of friendship. Run the interactive console using the following command:</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">$ python manage.py shell</span></pre>
<p>Next, retrieve some <em>User</em> objects and build relationships between them (but make sure that you have at least three users in the database):</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">&gt;&gt;&gt; from bookmarks.models import *</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; from django.contrib.auth.models import User</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; user1 = User.objects.get(id=1)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; user2 = User.objects.get(id=2)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; user3 = User.objects.get(id=3)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; friendship1 = Friendship(from_friend=user1, to_friend=user2)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; friendship1.save()</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; friendship2 = Friendship(from_friend=user1, to_friend=user3)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; friendship2.save()</span></pre>
<p>Now, <em>user2</em> and <em>user3</em> are both friends of <em>user1</em>. To retrieve the list of <em>Friendship</em> objects associated with <em>user1</em>, use:</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">&gt;&gt;&gt; user1.friend_set.all()</span><br style="font-weight: bold;" /><span style="font-weight: bold;">[&lt;Friendship: user1, user2&gt;, &lt;Friendship: user1, user3&gt;]</span></pre>
<p>(The actual usernames in output were replaced with user1, user2, and user3 for clarity.)</p>
<p>As you may have already noticed, the attribute is named <em>friend_set</em> because we called it so using the <em>related_name</em> option when we created the <em>Friendship</em> model.</p>
<p>Next, let&#8217;s see one way to retrieve the <em>User</em> objects of user1&#8217;s friends:</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">&gt;&gt;&gt; [friendship.to_friend for friendship in </span><br style="font-weight: bold;" /><span style="font-weight: bold;"> user1.friend_set.all()]</span><br style="font-weight: bold;" /><span style="font-weight: bold;">[&lt;User: user2&gt;, &lt;User: user3&gt;]</span></pre>
<p>The last line of code uses a Python feature called &#8220;list&#8221; comprehension to build the list of <em>User</em> objects. This feature allows us to build a list by iterating through another list. Here, we built the <em>User</em> list by iterating over a list of <em>Friendship</em> objects. If this syntax looks unfamiliar, please refer to the <em>List Comprehension</em> section in the Python tutorial.</p>
<p>Notice that <em>user1</em> has <em>user2</em> as a friend, but the opposite is not true.</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">&gt;&gt;&gt; user2.friend_set.all()</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> []</span></pre>
<p>In other words, the <em>Friendship</em> model works only in one direction. To add <em>user1</em> as a friend of <em>user2</em>, we need to construct another <em>Friendship</em> object.</p>
<pre style="margin-left: 40px;"><span style="font-weight: bold;">&gt;&gt;&gt; friendship3 = Friendship(from_friend=user2, to_friend=user1)</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; friendship3.save()</span><br style="font-weight: bold;" /><span style="font-weight: bold;">&gt;&gt;&gt; user2.friend_set.all()</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> [&lt;Friendship: user2, user1&gt;]</span></pre>
<p>By reversing the arguments passed to the <em>Friendship</em> constructor, we built a relationship in the other way. Now <em>user1</em> is a friend of <em>user2</em> and vice-versa. Experiment more with the model to make sure that you understand how it works. Once you feel comfortable with it, move to the next section, where we will write views to utilize the data model. Things will only get more exciting from now on!</p>
<h1>Writing views to manage friends</h1>
<p>Now that we are able to store and retrieve user relationships, it&#8217;s time to create views for these features. In this section we will build two views: one for adding a friend, and another for listing friends and their bookmarks.</p>
<p>We will use the following URL scheme for friend-related views:</p>
<ul>
<li>If the view is for managing friends (adding a friend, removing a friend, and so on), its URL should start with /friend/. For example, the URL of the view that adds a friend will be <em>/friend/add/</em>.</li>
<li>If the view is for viewing friends and their bookmarks, its URL should start with /friends/. For example, <em>/friends/username/</em> will be used to display the friends of username.</li>
</ul>
<p>This convention is necessary to avoid conflicts. If we use the prefix <em>/friend/</em> for all views, what happens if a user registers the username add? The Friends page for this user will be <em>/friend/add/</em>, just like the view to add a friend. The first URL mapping in the URL table will always be used, and the second will become inaccessible, which is obviously a bug.</p>
<p>Now that we have a URL scheme in mind, let&#8217;s start with writing the friends list view.</p>
<h2>The friends list view</h2>
<p>This view will receive a username in the URL, and will display this user&#8217;s friends and their bookmarks. To create the view, open the <em>bookmarks/views.py</em> file and add the following code to it:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> friends_page<span style="color: black;">&#40;</span>request, username<span style="color: black;">&#41;</span>:
  <span style="color: #dc143c;">user</span> = get_object_or_404<span style="color: black;">&#40;</span>User, username=username<span style="color: black;">&#41;</span>
  friends = <span style="color: black;">&#91;</span>friendship.<span style="color: black;">to_friend</span> <span style="color: #ff7700;font-weight:bold;">for</span> friendship <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">user</span>.<span style="color: black;">friend_set</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
  friend_bookmarks = Bookmark.<span style="color: black;">objects</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>user__in=friends<span style="color: black;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-id'</span><span style="color: black;">&#41;</span>
  variables = RequestContext<span style="color: black;">&#40;</span>request, <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'username'</span>: username,
    <span style="color: #483d8b;">'friends'</span>: friends,
    <span style="color: #483d8b;">'bookmarks'</span>: friend_bookmarks<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">10</span><span style="color: black;">&#93;</span>,
    <span style="color: #483d8b;">'show_tags'</span>: <span style="color: #008000;">True</span>,
    <span style="color: #483d8b;">'show_user'</span>: <span style="color: #008000;">True</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span><span style="color: #483d8b;">'friends_page.html'</span>, variables<span style="color: black;">&#41;</span></pre></div></div>

<p>This view is pretty simple. It receives a username and operates upon it as follows:</p>
<ul>
<li>The <em>User</em> object that corresponds to the username is retrieved using the shortcut method <em>get_object_or_404</em>.</li>
<li>The friends of this user are retrieved using the list comprehension syntax mentioned in the previous section.</li>
<li>After that, the bookmarks of the user&#8217;s friends are retrieved using the <em>filter</em> method. The <em>user_in</em> keyword argument is passed to <em>filter</em> in order to retrieve all the bookmarks of the user who exists in the friends list. <em>order_by</em> is chained to filter for the purpose of sorting bookmarks by <em>id</em> in a descending order.</li>
<li>Finally, the variables are put into a <em>RequestContext</em> object and are sent to a template named <em>friends_page.html</em>. We used the index syntax with <em>friend_bookmarks</em> to get only the latest ten bookmarks.</li>
</ul>
<p>Let&#8217;s write the view&#8217;s template next. Create a file called <em>friends_page.html</em> in the <em>templates</em> folder with the following code in it:</p>
<pre style="margin-left: 40px;">{% extends "base.html" %}

{% block title %}Friends for {{ username }}{% endblock %}
{% block head %}Friends for {{ username }}{% endblock %}

{% block content %}
 &lt;h2&gt;Friend List&lt;/h2&gt;
 {% if friends %}
 &lt;ul class="friends"&gt;
 {% for friend in friends %}
 &lt;li&gt;&lt;a href="/user/{{ friend.username }}/"&gt;
 {{ friend.username }}&lt;/a&gt;&lt;/li&gt;
 {% endfor %}
 &lt;/ul&gt;
 {% else %}
 &lt;p&gt;No friends found.&lt;/p&gt;
 {% endif %}

 &lt;h2&gt;Latest Friend Bookmarks&lt;/h2&gt;
 {% include "bookmark_list.html" %}
{% endblock %}</pre>
<p>The template should be self-explanatory; there is nothing new in it. We iterate over the <em>friends</em> list and create a link for each friend. Next, we create a list of friend bookmarks by including the <em>bookmark_list.html</em> template.</p>
<p>Finally, we will add a URL entry for the view. Open the <em>urls.py</em> file and insert the following mapping into the <em>urlpatterns</em> list:</p>
<pre style="margin-left: 40px;">urlpatterns = patterns('',
 [...]
 <span style="font-weight: bold;"># Friends</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> (r'^friends/(w+)/$', friends_page),</span>
)</pre>
<p>This URL entry captures the username portion in the URL using a regular expression, exactly the way we did in the <em>user_page</em> view.</p>
<p>Although we haven&#8217;t created a view for adding friends yet, you can still see this view by manually adding some friends to your account (if you haven&#8217;t done so already). Use the interactive console to make sure that your account has friends, and then start the development server and point your browser to <em>http://127.0.0.1:8000/ friends/your_username/</em> (replacing <em>your_username</em> with your actual username). The resulting page will look something similar to the following screenshot:</p>
<p style="text-align: center;"><a href="http://www.displayofpatience.net/wp-content/uploads/2009/04/djangoweb-article2-image01.png"><img class="alignnone size-full wp-image-130" title="djangoweb-article2-image01" src="http://www.displayofpatience.net/wp-content/uploads/2009/04/djangoweb-article2-image01.png" alt="djangoweb-article2-image01" width="500" height="427" /></a></p>
<p>So, we now have a functional Friends page. It displays a list of friends along with their latest bookmarks. In the next section, we are going to create a view that allows users to add friends to this page.</p>
<h2>Creating the add friend view</h2>
<p>So far, we have been adding friends using the interactive console. The next step in building the friends feature is offering a way to add friends from within our web application.</p>
<p>The <em>friend_add</em> view works like this: It receives the username of the friend in <em>GET</em>, and creates a <em>Friendship</em> object accordingly. Open the <em>bookmarks/views.py</em> file and add the following view:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">@login_required
<span style="color: #ff7700;font-weight:bold;">def</span> friend_add<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'username'</span> <span style="color: #ff7700;font-weight:bold;">in</span> request.<span style="color: black;">GET</span>:
    friend = get_object_or_404<span style="color: black;">&#40;</span>User, username=request.<span style="color: black;">GET</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    friendship = Friendship<span style="color: black;">&#40;</span>from_friend=request.<span style="color: #dc143c;">user</span>,to_friend=friend<span style="color: black;">&#41;</span>
    friendship.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponseRedirect<span style="color: black;">&#40;</span><span style="color: #483d8b;">'/friends/%s/'</span> <span style="color: #66cc66;">%</span> request.<span style="color: #dc143c;">user</span>.<span style="color: black;">username</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #ff7700;font-weight:bold;">raise</span> Http404</pre></div></div>

<p>Let&#8217;s go through the view line by line:</p>
<ul>
<li>We apply the <em>login_required</em> decorator to the view. Anonymous users must log in before they can add friends.</li>
<li>We check whether a <em>GET</em> variable called <em>username</em> exists. If it does, we continue with creating a relationship. Otherwise, we raise a 404 page not found error.</li>
<li>We retrieve the user to be added as a friend using <em>get_object_or_404</em>.</li>
<li>We create a <em>Friendship</em> object with the currently logged-in user as the <em>from_friend</em> argument, and the requested username as the <em>to_friend</em> argument.</li>
<li>Finally, we redirect the user to their Friends page.</li>
</ul>
<p>After creating the view, we will add a URL entry for it. Open the <em>urls.py</em> file and add the highlighted line to it:</p>
<pre style="margin-left: 40px;">urlpatterns = patterns('',
 [...]
 # Friends
 (r'^friends/(w+)/$', friends_page),
 <span style="font-weight: bold;">(r'^friend/add/$', friend_add),</span>
)</pre>
<p>The &#8220;add friend&#8221; view is now functional. However, there are no links to use it anywhere in our application, so let&#8217;s add these links. We will modify the <em>user_page</em> view to display a link for adding the current user as a friend, and a link for viewing the user&#8217;s friends. Of course, we will need to handle special cases; you don&#8217;t want an &#8220;add friend&#8221; link when you are viewing your own page, or when you are viewing the page of one of your friends.</p>
<p>Adding these links will be done in the <em>user_page.html</em> template. But before doing so, we need to pass a Boolean flag from the <em>user_page</em> view to the template indicating whether the owner of the user page is a friend of the currently logged-in user or not. So open the <em>bookmarks/views.py</em> file and add the highlighted lines into the <em>user_page</em> view:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> user_page<span style="color: black;">&#40;</span>request, username<span style="color: black;">&#41;</span>:
  <span style="color: #dc143c;">user</span> = get_object_or_404<span style="color: black;">&#40;</span>User, username=username<span style="color: black;">&#41;</span>
  query_set = <span style="color: #dc143c;">user</span>.<span style="color: black;">bookmark_set</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'-id'</span><span style="color: black;">&#41;</span>
  paginator = Paginator<span style="color: black;">&#40;</span>query_set, ITEMS_PER_PAGE<span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">if</span> request.<span style="color: #dc143c;">user</span>.<span style="color: black;">is_authenticated</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    is_friend = Friendship.<span style="color: black;">objects</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>from_friend=request.<span style="color: #dc143c;">user</span>, to_friend=<span style="color: #dc143c;">user</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">else</span>:
    is_friend = <span style="color: #008000;">False</span>
  <span style="color: #ff7700;font-weight:bold;">try</span>:
    page_number = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>request.<span style="color: black;">GET</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'page'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: black;">&#40;</span><span style="color: #008000;">KeyError</span>, <span style="color: #008000;">ValueError</span><span style="color: black;">&#41;</span>:
    page_number = <span style="color: #ff4500;">1</span>
  <span style="color: #ff7700;font-weight:bold;">try</span>:
    page = paginator.<span style="color: black;">page</span><span style="color: black;">&#40;</span>page_number<span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">except</span> InvalidPage:
    <span style="color: #ff7700;font-weight:bold;">raise</span> Http404
  bookmarks = page.<span style="color: black;">object_list</span>
  variables = RequestContext<span style="color: black;">&#40;</span>request, <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'username'</span>: username,
    <span style="color: #483d8b;">'bookmarks'</span>: bookmarks,
    <span style="color: #483d8b;">'show_tags'</span>: <span style="color: #008000;">True</span>,
    <span style="color: #483d8b;">'show_edit'</span>: username == request.<span style="color: #dc143c;">user</span>.<span style="color: black;">username</span>,
    <span style="color: #483d8b;">'show_paginator'</span>: paginator.<span style="color: black;">num_pages</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">1</span>,
    <span style="color: #483d8b;">'has_prev'</span>: page.<span style="color: black;">has_previous</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'has_next'</span>: page.<span style="color: black;">has_next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'page'</span>: page_number,
    <span style="color: #483d8b;">'pages'</span>: paginator.<span style="color: black;">num_pages</span>,
    <span style="color: #483d8b;">'next_page'</span>: page_number + <span style="color: #ff4500;">1</span>,
    <span style="color: #483d8b;">'prev_page'</span>: page_number - <span style="color: #ff4500;">1</span>,
    <span style="color: #483d8b;">'is_friend'</span>: is_friend,<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span><span style="color: #483d8b;">'user_page.html'</span>, variables<span style="color: black;">&#41;</span></pre></div></div>

<p>Next, open the <em>templates/user_page.html</em> file and add the following highlighted lines to it:</p>
<pre style="margin-left: 40px;">[...]
{% block content %}
 <span style="font-weight: bold;">{% ifequal user.username username %}</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> &lt;a href="/friends/{{ username }}/"&gt;view your friends&lt;/a&gt;</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {% else %}</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {% if is_friend %}</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> &lt;a href="/friends/{{ user.username }}/"&gt;</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {{ username }} is a friend of yours&lt;/a&gt; </span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {% else %}</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> &lt;a href="/friend/add/?username={{ username }}"&gt;</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> add {{ username }} to your friends&lt;/a&gt; </span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {% endif %}</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> - &lt;a href="/friends/{{ username }}/"&gt;</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> view {{username }}'s friends&lt;/a&gt;</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> {% endifequal %}</span>
 {% include "bookmark_list.html" %}
{% endblock %}</pre>
<p>Let&#8217;s go through each conditional branch in the highlighted code:</p>
<ol>
<li>We check whether the user is viewing his or her page. This is done using a template tag called <em>ifequal</em>, which takes two variables to compare for equality. If the user is indeed viewing his or her page, we simply display a link to it.</li>
<li>We check whether the user is viewing the page of one of their friends. If this is the case, we display a link to the current user&#8217;s Friends page instead of an &#8220;add friend&#8221; link. Otherwise, we construct an &#8220;add friend&#8221; link by passing the username as a <em>GET</em> variable.</li>
<li>We display a link to the Friends page of the user page&#8217;s owner being viewed.</li>
</ol>
<p>And that&#8217;s it. Browse some user pages to see how the links at the top change, depending on your relationship with the owner of the user page. Try to add new friends to see your Friends page grow.</p>
<p>Implementing the friends feature wasn&#8217;t that hard, was it? You wrote one data model and two views, and the feature became functional. Interestingly, the more Django experience you gain, the more easy and fast its implementation becomes.</p>
<p>Our users are now able to add each other as friends and monitor their friends&#8217; bookmarks.</p>
<h1>Summary</h1>
<p>In this article we developed an important feature for our project. Friend networks are very important in helping users to socialize and share interests together. These features are common in Web 2.0 applications, and now you are able to incorporate them into any Django web site.</p>
<p> </p>
<hr size="1" noshade="noshade" /><strong>If you have read this article you may be interested to view :</strong></p>
<p> </p>
<p> </p>
<ul>
<li><a href="http://www.packtpub.com/article/friends-via-email-social-web-application-django-1.0?utm_source=rk_djangoweb_abr2_0309&amp;utm_medium=content&amp;utm_campaign=ramsai" target="_blank">Inviting Friends via Email on Social Web Application with Django 1.0</a></li>
<li><a href="http://www.packtpub.com/article/creating-administration-interface-with-django-1.0?utm_source=rk_djangoweb_abr2_0309&amp;utm_medium=content&amp;utm_campaign=ramsai" target="_blank">Creating an Administration Interface with Django 1.0</a></li>
<li><a href="http://www.packtpub.com/article/multiple-templates-in-django?utm_source=rk_djangoweb_abr2_0309&amp;utm_medium=content&amp;utm_campaign=ramsai" target="_blank">Multiple Templates in Django</a></li>
</ul>
<p> </p>
<hr size="1" noshade="noshade" /> </p>
<p> </p>
<h1>About the Author</h1>
<p><strong>Ayman Hourieh</strong> holds a bachelor degree in Computer Science. He joined the engineering team at Google in January 2008. Prior to that, he worked with web application development for more than two years. In addition, he has been contributing to several open source projects such as Mozilla Firefox. Ayman also worked as a teaching assistant in Computer Science courses for one year. Even after working with a variety of technologies, Python remains Ayman&#8217;s favorite programming language. He found Django to be a powerful and flexible Python framework that helps developers to produce high-quality web applications in a short time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/04/django-10-website-development-by-ayman-hourieh-preview/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Zen of Python</title>
		<link>http://www.displayofpatience.net/2009/04/the-zen-of-python/</link>
		<comments>http://www.displayofpatience.net/2009/04/the-zen-of-python/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 09:01:47 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=98</guid>
		<description><![CDATA[Here&#8217;s a little &#8220;textual motivational poster&#8221; for all of you, who are writing code. Even though it&#8217;s about Python, I think it can be applied to almost anything   Anyway, it&#8217;s something to think about.

&#62;&#62;&#62; import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a little &#8220;textual motivational poster&#8221; for all of you, who are writing code. Even though it&#8217;s about Python, I think it can be applied to almost anything <img src='http://www.displayofpatience.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Anyway, it&#8217;s something to think about.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> this</pre></div></div>

<pre>The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/04/the-zen-of-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Test-driving Django-application development</title>
		<link>http://www.displayofpatience.net/2009/02/test-driving-django-application-development/</link>
		<comments>http://www.displayofpatience.net/2009/02/test-driving-django-application-development/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 16:27:53 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[sw development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[test-driven development]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=78</guid>
		<description><![CDATA[Test-Driven Development (TDD) is something that I’m currently really excited about. It’s nothing new in the world of software development, but it’s very new to me. I have read lots about it but I haven’t been able to start experiencing with it at work for various reasons (excuses!).  Anyway, finally I decided to start [...]]]></description>
			<content:encoded><![CDATA[<p>Test-Driven Development (TDD) is something that I’m currently really excited about. It’s nothing new in the world of software development, but it’s very new to me. I have read lots about it but I haven’t been able to start experiencing with it at work for various reasons (excuses!).  Anyway, finally I decided to start a personal project of my own, where I would begin to start learning TDD in practice. I chose to re-create a webstore-application I had previously written in PHP many years ago. I guess it would’ve been easier to start with something else than web-development but I’ve been playing around with a webframework called Django, which is excellent, and I figured I should combine those two.  For a second I thought about using some PHP framework like Zend, but I just prefer Python.</p>
<p>I started by googling, if someone had used TDD while developing Django-applications. There was not much to be found, and for the most part it was outdated.  However, I found some interesting blog posts about testing in general with django. I especially found <a href="http://www.stonemind.net/blog/2007/01/12/small-django-tips-from-one-newbie-to-another/">small django tips from one newbie to another</a> by Adam Smith very useful. I had worked with Django before and I knew the basics of TDD so low search results didn’t matter much. I was ready to begin.</p>
<p>The first thing I did was to set-up the development environment. I created the Django-project and the app inside it. I guess there are many ways you could Test-Drive in this situation but I wanted to use Django’s way of testing. So basically this means that I need to run the tests by executing “manage.py test” within my project. This will sniff the insides of django-applications for tests.py file (and models.py with tests inside that). The result of the command is the same you get from standard Python unittests runs. Of course you can specify the app with the command, but in the beginning there is just one app to begin with, so it was ok to run all tests.  Everything so far, was created by Django, including example tests.py file within the application. You can use Python Unittest or Docstring frameworks. I chose Unittest, since I’m more familiar with the xUnit frameworks such as JUnit. I think there was a mention in the Django docs, that you can also use other test tools.</p>
<p>I experimented a little with the Python interactive interpreter on how the tests work. At this time I started to think that having just one tests.py is going get crowded pretty soon so I created a module my_tests under the application and created model_tests.py and view_tests.py under it. I figured I wanted to keep the views as compact as possible and write the logic to either to the model classes or somewhere else, which would be decided later. For now, model and view tests should be enough to get me started. I also wanted to separate my test files from the actual code. Here is a sketch of my project configuration:</p>
<pre>Django-project/
--settings.py
--/my_webstore_application/
----views.py
----models.py
----tests.py
------/my_tests/
--------model_tests.py
--------view_tests.py
--------test_utils.py</pre>
<p>The tests.py is just a collection of suites:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
<span style="color: #ff7700;font-weight:bold;">import</span> my_tests.<span style="color: black;">view_tests</span>
<span style="color: #ff7700;font-weight:bold;">import</span> my_tests.<span style="color: black;">model_tests</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> suite<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    suite1 = <span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestLoader</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">loadTestsFromModule</span><span style="color: black;">&#40;</span>my_tests.<span style="color: black;">view_tests</span><span style="color: black;">&#41;</span>
    suite2 = <span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestLoader</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">loadTestsFromModule</span><span style="color: black;">&#40;</span>my_tests.<span style="color: black;">model_tests</span><span style="color: black;">&#41;</span>
    alltests = <span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestSuite</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>suite1, suite2<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> alltests</pre></div></div>

<p>I also created a run-configuration for Eclipse, so the RED-GREEN-REFACTOR –cycle would be as fluent as possible.  Here are some of the first tests I wrote (These are actually somewhat refactored, but the basic idea has remained):</p>
<p>*model_tests.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: #dc143c;">test</span> <span style="color: #ff7700;font-weight:bold;">import</span> TestCase
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">files</span>.<span style="color: black;">images</span> <span style="color: #ff7700;font-weight:bold;">import</span> ImageFile  
<span style="color: #ff7700;font-weight:bold;">from</span> webstore.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Product, Category, SubCategory, Image
<span style="color: #ff7700;font-weight:bold;">from</span> utils <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ProductTest<span style="color: black;">&#40;</span>TestCase<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> test_create_product<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        product = Product<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'test product 1'</span>, price=<span style="color: #483d8b;">&quot;15.50&quot;</span>, 
                          description=<span style="color: #483d8b;">'What a great product!'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEquals</span><span style="color: black;">&#40;</span>product.<span style="color: black;">name</span>, <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>product<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> CategoryTest<span style="color: black;">&#40;</span>TestCase<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> test_create_category<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        category = Category<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'test category 1'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEquals</span><span style="color: black;">&#40;</span>category.<span style="color: black;">name</span>, <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>category<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>*view_tests.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: #dc143c;">test</span>.<span style="color: black;">client</span> <span style="color: #ff7700;font-weight:bold;">import</span> Client
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: #dc143c;">test</span> <span style="color: #ff7700;font-weight:bold;">import</span> TestCase
<span style="color: #ff7700;font-weight:bold;">from</span> utils <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> merinostore.<span style="color: black;">webstore</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ProductTest<span style="color: black;">&#40;</span>TestCase<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> setUp<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">client</span> = Client<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">category</span> = Category<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'test category 1'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">category</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">subcategory</span> = SubCategory<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'test subcategory 2'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">subcategory</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">product</span> = Product<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'test product 1'</span>, price=<span style="color: #483d8b;">'15.50'</span>, 
                               description=<span style="color: #483d8b;">'What a great product!'</span>,
                               category=<span style="color: #008000;">self</span>.<span style="color: black;">category</span>, subcategory=<span style="color: #008000;">self</span>.<span style="color: black;">subcategory</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">product</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> 
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> test_list_products_template<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        response = <span style="color: #008000;">self</span>.<span style="color: black;">client</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/products/'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">failUnlessEqual</span><span style="color: black;">&#40;</span>response.<span style="color: black;">status_code</span>, <span style="color: #ff4500;">200</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertTemplateUsed</span><span style="color: black;">&#40;</span>response, <span style="color: #483d8b;">'product/list_products.html'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> test_list_products<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        create_products<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">category</span>, amount=<span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
        response = <span style="color: #008000;">self</span>.<span style="color: black;">client</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/products/'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">failUnlessEqual</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>response.<span style="color: black;">context</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'products'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, <span style="color: #ff4500;">11</span><span style="color: black;">&#41;</span></pre></div></div>

<p>So I started with the models. I soon figured out that at this point there is virtually no code created by me in models so I stopped doing those and concentrated on the view tests. If the models are broken, they cannot be used anywhere. Later I started to write some more model tests, as I defined my own functions for them.  As you can see, I use the Django helpers such as Client, which can be used to emulate the browser.  I also use Django’s own TestCase class for assertions.</p>
<p>I was a little bit concerned about testing through views. This means I deal with real instances of the models, which exist in the database. It isn’t unit testing anymore if the tests hit the database, right? Luckily, Django’s test system is pretty good by default. It creates in-memory sqlite database for testing and you can even use fixtures with that. I just couldn’t find any reason for doing any heavier separation between the code and the database as running the tests were fast enough for me.  Webstore application itself is mostly just about displaying items from the database. Of course, with the order handling and such tasks, I still plan to keep the logic separated from the views as much as possible. I figured as long as I write tests in order to drive design, it’s good.</p>
<p>I’m still in the process of developing the application, I have just finished the first feature, which is displaying of product list by categories (I copied the html stuff from the old store). What I didn’t do is test drive the templates. It just feels too much work, but I guess I could try that one as well. </p>
<p>I’m quite happy about the whole process in generally. At first I felt that I was proceeding very slowly, but at the same time it felt surprisingly good to get the GREEN showing up. I also created a simple script to import the data  (products for now) from my previous webstore implementation, and I didn’t use TDD for that. The reason I didn’t Test-Drive is because I felt the script is so small and will be used only once so I wanted just to be done with it.  It turned out to be hideous, and now I feel bad I didn’t TDD it (I think I’m going to rewrite that as well for practice). So I guess I’m learning something!</p>
<p>I’ll post more on the subject as I proceed or get the application ready. I’m sure that my tests aren’t very good and I’m doing many things wrong, but in order to better myself I hope I get some feedback. Till next time!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/02/test-driving-django-application-development/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Tracker music</title>
		<link>http://www.displayofpatience.net/2009/01/tracker-music/</link>
		<comments>http://www.displayofpatience.net/2009/01/tracker-music/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 22:04:27 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[music]]></category>
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=69</guid>
		<description><![CDATA[As we were having our long friday coffee break at work, the discussion turned into music, which really is not that uncommon. Only this time we talked about tracker / mod music (nerds as we are), among other things, which lead me to do some googling. And what did I find? A song created by [...]]]></description>
			<content:encoded><![CDATA[<p>As we were having our long friday coffee break at work, the discussion turned into music, which really is not that uncommon. Only this time we talked about <a href="http://en.wikipedia.org/wiki/Tracker">tracker / mod music</a> (nerds as we are), among other things, which lead me to do some googling. And what did I find? A song created by me in 1996!</p>
<p>To those of you who don&#8217;t know about tracking, it&#8217;s a form of computer music which was quite common especially in the amiga times and nineties. It is usually tightly coupled with <a href="http://en.wikipedia.org/wiki/Demoscene">demoscene</a>. I never tracked with amiga, but I used PC and a great software called Scream Tracker (ok, I used Fast Tracker too, but all my releases were with Scream Tracker). Oh, those were good times <img src='http://www.displayofpatience.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Anyway, tracker or mod-music is composed using samples and originally only four channels (later, when I did it, it was something like 16 or more depending on your cpu). Using samples you created patterns, which put together, made the song.</p>
<p>You can find my song and others from <a href="http://modarchive.org/index.php?request=view_by_moduleid&amp;query=34582">The Mod Archive</a> (where you can play it online) or from <a href="http://www.timpatton.com/nirvana/framefiles.html">Come As You are</a> for example. It seems that even Winamp can play mods nowadays. The song is called Breed (S3M) and it&#8217;s a Nirvana cover. Listening to it now, over ten years later, it sounds kind of crappy but I have to say I&#8217;m very delighted for finding out, that something I created as a teenager, has survived this long. Damn, maybe I should continue with music, my next song could be Frances Farmer Will Have Her Revenge On Seattle&#8230;</p>
<p>Breed wasn&#8217;t the only song I did (it was the only cover though), but it looks like the rest are lost in time (they probably never were on the web, back in the days we used mostly phone-based BBS systems). It&#8217;s a shame I didn&#8217;t keep copies. It would&#8217;ve been fun to listen to them now (or embarrassing at least).</p>
<p>There were some documentation attached to the S3M file, which among other things, listed my equipment. I still have the same Ibanez guitar (well, it&#8217;s broken but it hangs on my wall) and the same guitar amp (Marshall Valvestate) I used to record the riffs. Hmm.. it&#8217;s about time for a new amp! </p>
<p>If you want to listen to some great mod music, try googling or searching the mod archive for songs by Purple Motion and Skaven. They were from the demoscene group Future Crew, and were one of my favorites. There were other great artists too, but unfortunately I&#8217;ve forgotten their names. Long live tracker music!</p>
<p>EDIT: I actually found another song by me, though this wasn&#8217;t on internet: <a href="http://www.displayofpatience.net/wp-content/uploads/2009/01/outsider.s3m">The Outsider</a>. That one is 100% original and includes some vocal samples from Blur and Scorpions. The first part is pretty boring but if you forward to 2:00 there&#8217;s some nice acoustic outro, which actually sound pretty good. Check it out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/01/tracker-music/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SOWISA, babyluv – Stephen King: Lisey’s Story</title>
		<link>http://www.displayofpatience.net/2009/01/sowisa-babyluv-%e2%80%93-stephen-king-lisey%e2%80%99s-story/</link>
		<comments>http://www.displayofpatience.net/2009/01/sowisa-babyluv-%e2%80%93-stephen-king-lisey%e2%80%99s-story/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 18:51:12 +0000</pubDate>
		<dc:creator>bodhi</dc:creator>
				<category><![CDATA[literature]]></category>
		<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://www.displayofpatience.net/?p=65</guid>
		<description><![CDATA[
I just finished reading Lisey’s Story by Stephen King. Before I get into details, I have to say, that King is one of my all-time favorite authors. Needless to say, I was very eager to get my hands on Lisey’s Story, as it was just recently published in Finland (late 2008 I think). My dear [...]]]></description>
			<content:encoded><![CDATA[<p><!--StartFragment--></p>
<p class="MsoNormal"><span lang="EN-US">I just finished reading Lisey’s Story by Stephen King. Before I get into details, I have to say, that King is one of my all-time favorite authors. Needless to say, I was very eager to get my hands on Lisey’s Story, as it was just recently published in Finland (late 2008 I think). My dear mother was kind enough to buy it for me as a Christmas present, so thanks mom! Anyway, I find it really strange, how many people seem to really dislike King, even hate his books. Most of my friends, for example, belong to this group. On the other hand, his novels are bestsellers on a regular basis. Lisey’s story is no exception, and I’m sure, that it will once again divide the public.</span></p>
<p class="MsoNormal"><span lang="EN-US">The novel is oddly (for King that is) described as a love story and that it sure seems to be. It’s not exactly conventional, as the story begins when the other part of the relationship has been dead for quite some time. And of course, like in most of King’s novels, the supernatural is present. I think that is the biggest single factor that alienates people from King. The supernatural. But there is another side to that as well. Why I love King, has almost nothing to do with supernatural, or even horror. It’s about imagination and stories. Stories well told. If you think alike, Lisey’s Story is definitely for you. It’s celebration of imagination.</span></p>
<p class="MsoNormal"><span lang="EN-US">To be honest, I had great difficulties when I first started to read the novel. I wasn’t quite sure if I liked the story or not, and there were some strange made-up words that didn’t feel right, as it made the story feel somewhat childish, though that was intentional as it turned out later. I’m sure, that many will not give the story a chance and quit reading before they reach even the middle point. I’m glad I struggled on, because Lisey’s Story turned out be one the best novels, King has written in a long time. There are some horror elements in it, but mostly it’s focused on feelings such as love and loss. It’s a beautiful story of a man and a woman, about sanity and insanity, about facing your fears, and most of all; it’s a study of imagination.</span></p>
<p class="MsoNormal"><span lang="EN-US">SOWISA, Strap On Whenever It Seems Appropriate, is one the tiny things that I will surely remember from Lisey’s Story for years to come. It’s something that Scott Landon, the deceased husband of Lisey used to say to her, to babyluv. Scott and Lisey had a language of their own, and as a reader you begin to understand it better and better as the story proceeds. At the same time you are dwelled deeper and deeper to the mind of Scott and Lisey, and the theme of the novel becomes more obvious. What is the source of imagination and how close it is to insanity? </span></p>
<p class="MsoNormal"><span lang="EN-US">I loved this book. I will surely use it to measure people, but I fear many won’t like it at all. Those who will, I think I feel close to. If they like Lisey’s Story, they probably share the same longing, the same thrill about imagination.</span></p>
<p><!--EndFragment--></p>
]]></content:encoded>
			<wfw:commentRss>http://www.displayofpatience.net/2009/01/sowisa-babyluv-%e2%80%93-stephen-king-lisey%e2%80%99s-story/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
