<?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>Beardy Geek &#187; Web Development</title>
	<atom:link href="http://www.beardygeek.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.beardygeek.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 30 Jul 2010 21:48:02 +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>Django Training in the UK</title>
		<link>http://www.beardygeek.com/2010/07/django-training-in-the-uk/</link>
		<comments>http://www.beardygeek.com/2010/07/django-training-in-the-uk/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 21:48:02 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=150</guid>
		<description><![CDATA[In Autumn 2010 I will be running several Django courses throughout the UK.  The dates and locations will be based on demand, so please signup here to express your interest, and I&#8217;ll contact you when the venues have been arranged.
There will be 2 different types of courses:

Django template design &#8211; 1 day &#8211; for html/css [...]]]></description>
			<content:encoded><![CDATA[<p>In Autumn 2010 I will be running several Django courses throughout the UK.  The dates and locations will be based on demand, so please <a href="http://www.eventbrite.com/event/784050115?ref=elink" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.eventbrite.com/event/784050115?ref=elink&amp;referer=');">signup here</a> to express your interest, and I&#8217;ll contact you when the venues have been arranged.</p>
<p>There will be 2 different types of courses:</p>
<ul>
<li>Django template design &#8211; 1 day &#8211; for html/css coders who need to be able to fashion a template around the data being passed through by Django</li>
<li>Django introduction for programmers &#8211; 2 days &#8211; for those with web development experience who want to hit the ground running.</li>
</ul>
<p>The cost will be around the £200 per day mark.  I&#8217;ll publish more firm details soon.</p>
<p><a href="http://www.eventbrite.com/event/784050115?ref=ebtn" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.eventbrite.com/event/784050115?ref=ebtn&amp;referer=');"><img src="http://www.eventbrite.com/registerbutton?eid=784050115" border="0" alt="Register for Django Training UK on Eventbrite" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/07/django-training-in-the-uk/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New Django Site &#8211; Blog Twin</title>
		<link>http://www.beardygeek.com/2010/05/new-django-site-blog-twin/</link>
		<comments>http://www.beardygeek.com/2010/05/new-django-site-blog-twin/#comments</comments>
		<pubDate>Tue, 18 May 2010 22:30:08 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[site]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=136</guid>
		<description><![CDATA[I created Blog Twin after reading a blog post by Viper Chill entitled The Secret to growing your blog twice as fast with half the effort, I decided to create a site that would help people find a blogging partner.
Blog Twin is written in Django (naturally!).  You register, add details of your blog, and wait [...]]]></description>
			<content:encoded><![CDATA[<p>I created <a href="http://www.blogtwin.com/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.blogtwin.com/?referer=');">Blog Twin</a> after reading a blog post by Viper Chill entitled <a href="http://www.viperchill.com/fast-blog-growth/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.viperchill.com/fast-blog-growth/?referer=');">The Secret to growing your blog twice as fast with half the effort</a>, I decided to create a site that would help people find a blogging partner.</p>
<p><a href="http://www.blogtwin.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.blogtwin.com?referer=');">Blog Twin</a> is written in Django (naturally!).  You register, add details of your blog, and wait for someone else to come along and find you.  Or you can browse through and try and find a site in  a similar niche with similar stats to you.</p>
<p>There&#8217;s also the ability to tag entries, and filter by the tags.</p>
<p>It&#8217;s still a very early beta (I only started doing it 2 days ago), so any feedback, or bug reports, are most welcome.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/05/new-django-site-blog-twin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Website Stress testing using JMeter</title>
		<link>http://www.beardygeek.com/2010/03/website-stress-testing-using-jmeter/</link>
		<comments>http://www.beardygeek.com/2010/03/website-stress-testing-using-jmeter/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 13:33:54 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Video]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[performance testing]]></category>
		<category><![CDATA[stress testing]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=125</guid>
		<description><![CDATA[Here&#8217;s my latest screencast, showing you how to stress test your website and web applications using JMeter.
	
	
		
			
			
			
			
			
		
	www.youtube.com/watch?v=8NLeq-QxkSw
]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my latest screencast, showing you how to stress test your website and web applications using <a href="http://jakarta.apache.org/jmeter" target="_blank" onclick="pageTracker._trackPageview('/outgoing/jakarta.apache.org/jmeter?referer=');">JMeter</a>.</p>
<p>	<!-- Smart Youtube -->
	<span class="youtube">
		<object width="480" height="385">
			<param name="movie" value="http://www.youtube-nocookie.com/v/8NLeq-QxkSw&amp;rel=1&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0" />
			<param name="allowFullScreen" value="true" />
			<embed wmode="transparent" 
				src="http://www.youtube-nocookie.com/v/8NLeq-QxkSw&amp;rel=1&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0" 
				type="application/x-shockwave-flash" 
				allowfullscreen="true" 
				width="480" 
				height="385">
			</embed>
			<param name="wmode" value="transparent" />
		</object>
	</span><a href="http://www.youtube.com/watch?v=8NLeq-QxkSw" onclick="pageTracker._trackPageview('/outgoing/www.youtube.com/watch?v=8NLeq-QxkSw&amp;referer=');">www.youtube.com/watch?v=8NLeq-QxkSw</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/03/website-stress-testing-using-jmeter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding Views to the Django Admin</title>
		<link>http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/</link>
		<comments>http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 11:01:19 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=90</guid>
		<description><![CDATA[I recently had to write a view that had to be contained within the Django admin area, on a separate page from the models.  Here's the approach I took.]]></description>
			<content:encoded><![CDATA[<p>I recently had to write a view that exported data to csv.  The view had to be contained within the Django admin area, on a separate page from the rest of the apps and models.  Here is the approach I took.</p>
<h2>The Urls</h2>
<p>There are 2 ways to add urls to the admin: the quick and easy way, or the not so quick and easy way.  In this case, as I was only adding a single url, I went for the quick and easy way.  The other way involves extending the get_urls() method of AdminSite, adding to the existing admin url pattern.  I did this:</p>
<pre><code>
(r'^admin/mypage/$', 'myapp.views.my_admin_view'),
(r'^admin/', include(admin.site.urls)),
</code></pre>
<p>Make sure you add your page before the main admin include.</p>
<h2>The View</h2>
<p>When you write your view make sure you use the staff_member_required decorator.</p>
<pre><code>
from django.contrib.admin.views.decorators import staff_member_required
...
@staff_member_required
def my_admin_view(request):
    # view code
</code></pre>
<p>When rendering your view, also make sure you pass RequestContext to the template:</p>
<pre><code>
return render_to_response('my_template.html',
  context_instance=RequestContext(request))
</code>
</pre>
<h2>The Template</h2>
<p>So that your view looks like it belongs in the admin area, you need to extend the admin base site template:</p>
<pre>
<code>
{% extends 'admin/base_site.html' %}
</code>
</pre>
<p>You&#8217;ll also want to add in i18n support, and the admin media:</p>
<pre>
<code>
{% load i18n adminmedia %}
</code>
</pre>
<p>If you want to add in extra styles you can use {% block extrastyle %}, and you could put javascript in {% block extrahead %}.</p>
<h2>Adding form date widgets</h2>
<p>If you have a form on your page that includes date fields, you might want to have the nice django javascript form widgets.  First you need to add the widgets to your form:</p>
<pre>
<code>
from django.contrib.admin import widgets

class AdminForm(forms.Form):
    start_date = forms.DateField(label="Start date",
         widget=widgets.AdminDateWidget())
</code>
</pre>
<p>Next you need to add in the following to your extrahead block (replace admin-media with whatever you&#8217;ve set your admin media url to):</p>
<pre>
<code>
&lt;script type="text/javascript" src="/admin/jsi18n/"&gt;&lt;/script>
&lt;script type="text/javascript" src="/admin-media/js/core.js"&gt;&lt;/script&gt;
{{ form.media }}
</code>
</pre>
<p>You also need to add the admin forms css in the extrastyles block:<br />
<code></p>
<pre>
{{ block.super }}
&lt;link rel="stylesheet" type="text/css" href="/admin-media/css/forms.css" /&gt;
</pre>
<p></code></p>
<h2>Breadcrumbs</h2>
<p>If you want to have the breadcrumb trail at the top of the page, you need to create your own breadcrumb:</p>
<pre>
<code>
{% block breadcrumbs %}&lt;div class="breadcrumbs"&gt;&lt;a href="/admin/"&gt;
{% trans "Home" %}&lt;/a&gt; &gt; My View&lt;/div&gt;{% endblock %}
</code>
</pre>
<h2>Adding a link to the admin index</h2>
<p>When I add a link in, I like it to go in one of the right column boxes, so I usually create a new one and put it above the recent actions box.  To do this, you need to override the admin index.html file.</p>
<p>Create a directory in your templates directory called admin.  Then copy the index.html file from django/contrib/admin/templates to your new directory.</p>
<p>You&#8217;ll see a block called &#8217;sidebar&#8217;.  Under the &#8216;content-related&#8217; div, place the following:</p>
<pre>
<code>
&lt;div class="module"&gt;
  &lt;h2&gt;Admin tools&lt;/h2&gt;
    &lt;ul class="actionlist"&gt;
      &lt;li class="changelink"&gt;
        &lt;a href="/admin/mypage/"&gt;My View&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
</code>
</pre>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>New Django Site &#8211; The Great British Sleep Survey</title>
		<link>http://www.beardygeek.com/2010/03/new-django-site-the-great-british-sleep-survey/</link>
		<comments>http://www.beardygeek.com/2010/03/new-django-site-the-great-british-sleep-survey/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 20:05:29 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Featured]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=84</guid>
		<description><![CDATA[I've very recently finished a django based site for a company called Sleepio﻿. ]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve very recently finished a django based site for a company called <a title="Sleepio" href="http://www.sleepio.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.sleepio.com?referer=');">Sleepio</a>﻿.  The project was to create a survey site, called the Great British Sleep Survey. Once completed, it calculates your sleep score and creates a report tailored to your issues (or lack of).</p>
<p>Also working on the site, doing all the xhtml and css magic was Rui Zhang from <a href="http://borderleft.com/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/borderleft.com/?referer=');">borderleft</a>. If you ever need anyone to turn your designs into an actual web site, he&#8217;s your man. Thanks Rui.</p>
<p>One of the co-founders of Sleepio is Professor Colin Espie, who runs the sleep centre at Glasgow University.  The site is also a collaboration with <a href="http://www.webmd.boots.com/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.webmd.boots.com/?referer=');">Boots Web MD</a>, which offers health and medical advice.</p>
<p>So check it out, complete the survey (you get a free sleep report!), and any feedback is always welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2010/03/new-django-site-the-great-british-sleep-survey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django Tips &#8211; Unique Date Querysets</title>
		<link>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/</link>
		<comments>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 18:50:26 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=35</guid>
		<description><![CDATA[I swear this particular feature of querysets was made especially for the archive listing of a blog.  You know, the month and year listing in the side bar for all your previous posts. This solves that problem exactly.]]></description>
			<content:encoded><![CDATA[<p>I swear this particular feature of querysets was made especially for the archive listing of a blog.  You know, the month and year listing in the side bar for all your previous posts. This solves that problem exactly.</p>
<p>Let&#8217;s say you have a BlogPost model, and a post_date field within said model.  You want a list on the sidebar of all the unique month and year combinations.  Here&#8217;s what you do:</p>
<p><pre>
<code>
queryset = BlogPost.objects.dates('post_date', 'month')
</code>
</pre>
</p>
<p>And that&#8217;s it.  You&#8217;ll now have a query set full of datetime objects with all your unique months and years.</p>
<p>To get unique years only, substitute &#8216;year&#8217; for &#8216;month&#8217;, and for unique day, month and year, substitute &#8216;day&#8217; for &#8216;month&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/02/django-tips-unique-date-querysets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>From Wordpress to Django &#8211; Part 2</title>
		<link>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/</link>
		<comments>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 18:59:08 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=46</guid>
		<description><![CDATA[Welcome back.  In part 2 I'll be getting to the meat of the issue, which is retrieving the data from an existing Wordpress blog, and feeding the data into my own models.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.foundrylabs.co.uk/blog/2009/1/from-wordpress-to-django-part-one/" onclick="pageTracker._trackPageview('/outgoing/www.foundrylabs.co.uk/blog/2009/1/from-wordpress-to-django-part-one/?referer=');">View Part 1</a><br />
<a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">Beardy Geek Git Hub Repository</a></p>
<p>Welcome back.  In part 2 I&#8217;ll be getting to the meat of the issue, which is retrieving the data from an existing Wordpress blog, and feeding the data into my own models.</p>
<p>
<h4>Models</h4>
<p>I&#8217;ve decided to start the models from scratch, rather than trying to copy the way Wordpress has laid them out. It should keep things simpler that way.  I&#8217;ll be using the contrib comments system for the post comments, and I&#8217;ll also be creating 3 other models, Category, Tag, and Post. Here&#8217;s the code for the models:</p>
<pre><code>
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime

POST_STATUS = (
               ('P', 'Published'),
               ('U', 'Unpublished'),
)

class Tag(models.Model):
    text = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)

    def __unicode__(self):
        return self.text

class Category(models.Model):
    text = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)

    def __unicode__(self):
        return self.text

    class Meta:
        verbose_name_plural = "categories"

class Post(models.Model):
    title = models.CharField(max_length=75)
    slug = models.CharField(max_length=75)
    content = models.TextField()
    author = models.ForeignKey(User)
    post_date = models.DateTimeField(default=datetime.now)
    status = models.CharField(max_length=1, choices=POST_STATUS)
    categories = models.ManyToManyField(Category)
    tags = models.ManyToManyField(Tag)

    def __unicode__(self):
        return self.title
</code></pre>
</p>
<p>
<h4>Wordpress Export</h4>
<p>Just a quick note: I am using Wordpress Version 2.6.1. Things may be different in other versions, but the code here works on this version. I&#8217;ll go through the code so you should see where the problem is if it doesn&#8217;t work with your version.</p>
<p>OK, if you didn&#8217;t already know, you can export all your Wordpress data into an xml file. Go to your dashboard, click &#8216;Manage&#8217;, and then &#8216;Export&#8217;. Select which authors to restrict (if any) and hit the download button. You should now have the data in an xml file.</p>
<p>
<h4>XML File Editing</h4>
<p>When I first tried to parse this file, I got an error as one of the namespaces used in the document is undeclared. To rectify this, you need to open up the file in a text editor (not an xml editor, you may get the same parse error). Near the top of the file, you should see something like this:</p>
<pre><code>
&lt;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:wp="http://wordpress.org/export/1.0/"
&gt;
</code></pre>
<p>The missing namespace is &#8216;excerpt&#8217;, and we need to add this. It doesn&#8217;t matter what value you give it. I did this:</p>
<pre><code>
&lt;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:wp="http://wordpress.org/export/1.0/"
	xmlns:excerpt="mysite"
&gt;
</code></pre>
<p>Save the file and we&#8217;re ready to start parsing the data.</p>
<p>
<h4>XML Parsing</h4>
<p>To parse the XML I have used ElementTree. This is included in Python 2.5, but if you&#8217;re using an earlier version, you can get ElementTree from <a href="http://effbot.org" onclick="pageTracker._trackPageview('/outgoing/effbot.org?referer=');">Effbot.org</a>.</p>
<p>I won&#8217;t include all the code here, just some snippets as examples. To view the full source, please check out the <a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">BeardyGeek Github Repository</a>.</p>
<p>First we need to load our xml file.</p>
<pre><code>
tree = ElementTree.parse('c:/wordpress.xml')
</code></pre>
<p>Then find the top level under which our data resides, which is the &#8216;channel&#8217; tag.</p>
<pre><code>
chan = tree.find('channel')
</code></pre>
<p>Now I want to create some shortcut variables for the namespaces that we will use when finding tags.</p>
<pre>
<code>
wp_ns = '{http://wordpress.org/export/1.0/}'
content_ns = '{http://purl.org/rss/1.0/modules/content/}'
</code>
</pre>
<p>Now we can get all the category, tag and item(post) entries:</p>
<pre><code>
cats = chan.findall('{http://wordpress.org/export/1.0/}category')
tags = chan.findall('{http://wordpress.org/export/1.0/}tag')
items = chan.findall('item')
</code></pre>
<p>This will give us lists of all the elements for those three items.</p>
<p>
<h4>Finding and Saving Data</h4>
<p>I&#8217;ll give an example of saving the data using the category tag.</p>
<pre>
<code>
for cat in cats:
        c = Category(text=cat.find(wp_ns + 'cat_name').text,
                 slug=cat.find(wp_ns + 'category_nicename').text)
        c.save()
</code>
</pre>
<p>The tag data is the same as the above.</p>
<p>The item data is a bit more complex. If you look at the xml you&#8217;ve exported, you&#8217;ll see that the item data includes both posts and pages. But it also gives all previous revisions of each post, which will include any drafts saved whilst writing a post. So we need to find all those with a status of &#8216;publish&#8217; and a page type of &#8216;post&#8217;. We&#8217;ll deal with the &#8216;page&#8217; data another time, using Flatpages.</p>
<pre>
<code>
if item.find(wp_ns + 'status').text == 'publish' and
               item.find(wp_ns + 'post_type').text == 'post':
            i = Post(title=item.find('title').text,
                     slug=item.find(wp_ns + 'post_name').text,
                     content=item.find(content_ns + 'encoded').text, author=u,
                     post_date=item.find(wp_ns + 'post_date').text,
                     status='P')
            i.save()
</code>
</pre>
<p>The &#8216;u&#8217; (value for author) is a User object I create earlier in the code that I&#8217;ve used as the default author of each post (see source).</p>
<p>
<h4>Post Categories</h4>
<p>Now we have to find out which categories and tags this post has. Within each &#8216;item&#8217; we have &#8216;category&#8217; data. A bit confusingly this &#8216;category&#8217; data also includes the tags, and to discover that you need to look at the &#8216;domain&#8217; attribute to see which it is. Plus we only need the category with the &#8216;nicename&#8217; in it (slugified).</p>
<pre>
<code>
post_cats = item.findall('category')

for pc in post_cats:
     #check for attributes
     if pc.get('nicename'):
         if pc.attrib['domain'] == 'category':
              c2 = Category.objects.get(slug=pc.attrib['nicename'])
              i.categories.add(c2)
         elif pc.attrib['domain'] == 'tag':
              t2 = Tag.objects.get(slug=pc.attrib['nicename'])
              i.tags.add(t2)
</code>
</pre>
</p>
<p>
<h4>Comments</h4>
<p>The last section deals with comments. I am using the django.contrib.comments module for this.</p>
<pre>
<code><br />
comments = item.findall(wp_ns + 'comment')</p>
<p>for comm in comments:<br />
    if not comm.find(wp_ns + 'comment_author_email').text:<br />
        comm_email = ''<br />
    else:<br />
        comm_email = comm.find(wp_ns + 'comment_author_email').text</p>
<p>        if not comm.find(wp_ns + 'comment_author_url').text:<br />
            comm_url = ''<br />
        else:<br />
            comm_url = comm.find(wp_ns + 'comment_author_url').text</p>
<p>        db_comm = Comment(comment=comm.find(wp_ns + 'comment_content').text,<br />
            ip_address=comm.find(wp_ns + 'comment_author_IP').text,<br />
            object_pk=i.id, submit_date=comm.find(wp_ns + 'comment_date').text,<br />
            user_email=comm_email,<br />
            user_name=comm.find(wp_ns + 'comment_author').text[:50],<br />
            user_url=comm_url,<br />
            content_type=ct, site=site)<br />
        db_comm.save()<br />
</code>
</pre<br />
</p>
<p>
<h4>Conclusion</h4>
<p>Well that wraps it up for this post. I'll cover extracting the data for Flatpages in the next post, but this should give you enough to get started. You can see how to extract the required data from the xml document, so if you want to extend the models beyond what I have, you shouldn't have any problems.  Again, check out the fully code, plus the other file changes (url.py etc) at <a href="http://github.com/beardygeek/beardygeek-website" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">the Beardy Geek Git Hub Repository</a>. Have fun.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-two/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From Wordpress to Django &#8211; Part 1</title>
		<link>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/</link>
		<comments>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 18:55:00 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Blogging]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=43</guid>
		<description><![CDATA[Now don't get me wrong, there's nothing wrong with Wordpress.  It's just that I like to play with stuff, so I thought it would be fun to create a blog in Django, copy all my Wordpress posts across, and add at least some of the functionality that Wordpress has built in.]]></description>
			<content:encoded><![CDATA[<p>Now don&#8217;t get me wrong, there&#8217;s nothing wrong with Wordpress.  It&#8217;s just that I like to play with stuff, so I thought it would be fun to create a blog in Django, copy all my Wordpress posts across, and add at least some of the functionality that Wordpress has built in.</p>
<h4>Open Source</h4>
<p>Throughout this process, so that you can follow along, I will be storing the code in a GitHub repository.  <a href="http://github.com/beardygeek/beardygeek-website" target="_blank" onclick="pageTracker._trackPageview('/outgoing/github.com/beardygeek/beardygeek-website?referer=');">Click here to view the BeardyGeek repository</a></p>
<h4>A Few Considerations</h4>
<p>There are a few things to think about before getting started:</p>
<ol>
<li>Data Conversion &#8211; getting the data from Wordpress into my Django models.  Do I want to keep the same database structure as Wordpress, or create my own?  If I create my own, how will I get the data across?</li>
<li>Services &#8211; how much do I try and implement?  The main ones are comments, tags, pings, anti-spam.</li>
</ol>
<p>I&#8217;m sure more will come to mind as I go through this</p>
<h4>Conclusion</h4>
<p>Well, I&#8217;d better stop jabbering and get on with it then!  Keep an eye on the blog, or watch the Git repo for updates.  I&#8217;ll get done whatever my current workload allows.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/from-wordpress-to-django-part-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Call a .Net Webservice using Python</title>
		<link>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/</link>
		<comments>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 12:51:46 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[web service]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=8</guid>
		<description><![CDATA[Learn how to consume a .net webservice using Python]]></description>
			<content:encoded><![CDATA[<p>My day job involves working with software that automatically creates webservices on the .Net platform. Up until now I have used C# to create web applications to use these webservices.</p>
<p>But it would be nice to have the flexibility to use another programming language to create a solutions, and consume the webservices from there.</p>
<p>So, here&#8217;s a short tutorial on calling your .net webservice using Python.</p>
<p>
<h4>Pre-requisites</h4>
<ol>
<li>I&#8217;m currently using Python 2.5, so I can&#8217;t speak for other versions</li>
<li>You will need the ElementSoap package from effbot.org.  <a href="http://effbot.org/downloads/#elementsoap" onclick="pageTracker._trackPageview('/outgoing/effbot.org/downloads/_elementsoap?referer=');">You can get it from here</a></li>
<li>You&#8217;re also going to need a .Net webservice with which to test this out. If you&#8217;re reading this tutorial, you probably already have one.</li>
</ol>
<p>
<h4>SOAP</h4>
<p>Firstly we need to look at the SOAP examples on your .Net webservice.  Go your webservice&#8217;s asmx page, and then click on one of your webservices to view the details.  You will see some example SOAP requests and responses.  The one we&#8217;re interested in here is SOAP 1.1.  Mine looks like this:</p>
<pre>
<code>
POST /lookserver/webservices.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/GetVersion"

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  &lt;soap:Body&gt;
    &lt;getVersion xmlns="http://tempuri.org/" /&gt;
  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

&lt;xml version="1.0" encoding="utf-8"?&gt;
&lt;soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  &lt;soap:Body&gt;
    &lt;getVersionResponse xmlns="http://tempuri.org/"&gt;
      &lt;getVersionResult&gt;string&lt;/getVersionResult&gt;
    &lt;/getVersionResponse&gt;
  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</code>
</pre>
<p>As we can see here, I have a webservice called GetVersion, the namespace is http://tempuri.org, and the SOAPAction is http://tempuri.org/GetVersion.  Note these down for your webservice.
</p>
<p>
<h4>Into the Python</h4>
<p>Fire up an interactive session, and we&#8217;ll go through calling this service.</p>
<p>Firstly we need to import the ElementSOAP library:</p>
<pre>
<code>from elementsoap import ElementSOAP as ES</code>
</pre>
<p>
</p>
<p>If you get an error message, then you haven&#8217;t installed ElementSoap properly.
</p>
<p>Next we create a SoapRequest:</p>
<pre>
<code>sr = ES.SoapRequest("{http://tempuri.org/}GetVersion")</code>
</pre>
<p></p>
<p>And now we initialize a SoapService object:</p>
<pre>
<code>serv = ES.SoapService("http://localhost/lookserver/webservices.asmx")</code>
</pre>
<p></p>
<p>Obviously put in your own url for your webservice.</p>
<p>Now we call the webservice, using the SOAPAction value:</p>
<pre>
<code>result = serv.call("http://tempuri.org/GetVersion", sr)</code>
</pre>
<p></p>
<p>The result is an xml element which should contain the response from your webservice. When I type result I get:</p>
<pre>
<code>&lt;element '{http://tempuri.org/}GetVersionResponse' at 00A1A8A8&gt;</code>
</pre>
<p></p>
<p>If you look at the xml at the top of the article, you&#8217;ll see that the result returns inside a GetVersionResponse tag.  To get the value of the result we type:</p>
<pre>
<code>result.find("{http://tempuri.org/}GetVersionResult").text</code>
</pre>
<p></p>
<p>This finds the appropriate tag, and returns the text.
</p>
<p>&nbsp;</p>
<h4>Conclusion</h4>
<p>I hope this has helped.  When I searched, I found that the other tutorials were either confusing, or out of date.  Take a look at the various libraries at effbot.org, especially ElementTree for parsing XML, very useful.  Enjoy!</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2009/01/how-to-call-a-net-webservice-using-python/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Django and Ajax &#8211; using Prototype and Scriptaculous</title>
		<link>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/</link>
		<comments>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 18:53:00 +0000</pubDate>
		<dc:creator>BeardyGeek</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.beardygeek.com/?p=39</guid>
		<description><![CDATA[I started adding a sprinkling of Ajax in one of my Django projects, so I thought I'd share a few snippets that might help you add some Ajax goodness into your app.]]></description>
			<content:encoded><![CDATA[<p>I started adding a sprinkling of Ajax in one of my Django projects, so I thought I&#8217;d share a few snippets that might help you add some Ajax goodness into your app.</p>
<p>To handle the Ajax callbacks, I&#8217;ll be using <a href="http://www.prototypejs.org" onclick="pageTracker._trackPageview('/outgoing/www.prototypejs.org?referer=');">Prototype</a>, a lightweight Ajax library.  And for a couple of effects, like fade-in, I&#8217;ll be using <a href="http://script.aculo.us/" onclick="pageTracker._trackPageview('/outgoing/script.aculo.us/?referer=');">Scriptaculous</a>.</p>
<p>
<h4>Ajax Voting</h4>
<p>I wanted to add a Digg-like voter to my app, where you have the number of votes showing with a vote button, and when you click on the vote button, the number disappears, then fades back in with an increase in the vote.  The new vote will be added to the database.  I also wanted to only allow each user to only vote on each item once (for obvious reasons!)</p>
<p>
<h4>Overview</h4>
<p>Here&#8217;s how it hangs together. The user presses the vote button. This calls back to a url, which has a view, which retrieves and/or stores data, which then renders the output to a template, which is then inserted by magic under the button with the new stored value.</p>
<p>Now on with some code.</p>
<p>
<h4>Urls</h4>
<p>First we need to define a url for the callback.</p>
<pre>
<code>url(r'^callback/vote/(?P<item_id>\d+)/$', 'vote', name='callback_vote'),</code>
</pre>
</p>
<p>
<h4>Models</h4>
<p>For the purposes of this post, I&#8217;ll create 2 models.  The first is an item model, where we can store an item description, and the number of the votes that item has:</p>
<pre>
<code>
class Item(models.Model):
    item_desc = models.CharField(max_length=200)
    votes = models.IntegerField()
</code>
</pre>
<p>Now we can create a Voter model, which stores who voted for which item, so we can prevent multiple voting for each user:</p>
<pre>
<code>
from django.contrib.auth.models import User

class Voter(models.Model):
    voter = models.ForeignKey(User)
    item = models.ForeignKey(Item)
</code>
</pre>
</p>
<p>
<h4>Script Tags</h4>
<p>Now we need to import the Javascript for Prototype and Scriptaculous. We can either do this in our base.html, which means the javascript will be loaded on every page, or we could add a block into the header, and just load the javascript on a per page basis. I have also stored the scripts in my MEDIA_URL.</p>
<pre>
<code>
&lt;script type="text/javascript" src="{{ MEDIA_URL }}scripts/prototype.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"
    src="{{ MEDIA_URL }}scripts/scriptaculous.js?load=effects"&gt;&lt;/script&gt;
</code>
</pre>
<p>You&#8217;ll see the load=effects option after the scriptaculous url. This is so it doesn&#8217;t load all of the modules. You can if you want, but for this example we only need the effect module.
</p>
<p>
<h4>Prototype Script</h4>
<p>For the prototype script to work, and update our vote number, we need to have a page element to update. You could have a div or a span, but you need to give the element an id and a name.</p>
<p>Now for the script.</p>
<pre>
<code>
&lt;script type="text/javascript"&gt;
	function addVote(item_id) {
		$('item').style.display = 'none';
		var ajax = new Ajax.Request('callback/vote/' + item_id + '/', {
				method: 'get',
				onSuccess: function(transport) {
					var result = $('item');
					result.update(transport.responseText);
				}
			});
		$('item').appear();
	}
&lt;/script&gt;
</code>
</pre>
<p>I&#8217;m assuming we&#8217;ve called the span or div id &#8216;item&#8217;. The $(&#8216;item&#8217;) is a short cut to get a reference to the element. Firstly we call the function with the item id as a parameter. Then we set the display to &#8216;none&#8217; before doing the callback. The callback is done, we update the div element using result.update, and the final line uses the Scriptaculous &#8216;appear()&#8217; function, which fades the div back in.</p>
<p>Don&#8217;t forget to add an onclick() or similar event to what ever you want to use to trigger the callback. In my case I used the tick image.</p>
<pre>
<code>
&lt;a onclick="addVote({{ n.id }})"&gt;&lt;img src"..." /&gt;&lt;/a&gt;
</code>
</pre>
<p>I used n as a context for my item on the view for this page, in case you&#8217;re wondering what the {{ n.id }} is for.</p>
<p>
<h4>Callback Code</h4>
<p>Now we have the client side script, we need to take that item id and do something with it, then return the result for display.</p>
<p>First we need to create the vote view.</p>
<pre>
<code>
def vote(request, item_id):
    i = Item.objects.get(pk=item_id)
    #see if user has voted
    voter = Voter.objects.filter(voter=request.user, item=i)

    if not voter:
        v = Voter(voter=request.user, item=i)
        v.save()
        i.votes += 1
        i.save()

    return render_to_response('item/callback_vote.html', {'votes':i.votes})
</code>
</pre>
<p>We get our item object first, then check the Voter model to see if the current logged in user has already voted for this item. If they haven&#8217;t, then we create a Voter entry, and increase the number of votes by one. We then return the number of votes in the context.</p>
<p>
<h4>Callback Template</h4>
<p>Now we create a simple template to display the vote view.</p>
<pre>
<code>
{{ votes }}
</code>
</pre>
</p>
<p>
<h4>Conclusion</h4>
<p>And there we have it. That&#8217;s the basics of Ajax in Django. There&#8217;s a lot more to Scriptaculous than just the fade and appear, so check it out.</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.beardygeek.com/2008/12/django-and-ajax-using-prototype-and-scriptaculous/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
