<?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>Tom Coote &#187; Django</title>
	<atom:link href="http://tomcoote.co.uk/category/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://tomcoote.co.uk</link>
	<description>An ace web developer!</description>
	<lastBuildDate>Sun, 08 Jan 2012 14:18:38 +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 Site Login Script</title>
		<link>http://tomcoote.co.uk/django/django-site-login-script/</link>
		<comments>http://tomcoote.co.uk/django/django-site-login-script/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 14:18:38 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=722</guid>
		<description><![CDATA[
			
				
			
		
Just having a play around with a Python script that will login to a standard Django login form. I thought I&#8217;d share it as it&#8217;s quite interesting and I&#8217;m sure someone might find a use for it.
It uses the standard Python modules urllib2, urllib and cookielib. It also requires BeautifulSoup for getting the generated CSRF [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fdjango-site-login-script%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fdjango-site-login-script%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Just having a play around with a Python script that will login to a standard Django login form. I thought I&#8217;d share it as it&#8217;s quite interesting and I&#8217;m sure someone might find a use for it.</p>
<p>It uses the standard Python modules <a href="http://docs.python.org/library/urllib2.html">urllib2</a>, <a href="http://docs.python.org/library/urllib.html">urllib</a> and <a href="http://docs.python.org/library/cookielib.html">cookielib</a>. It also requires <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a> for getting the generated CSRF token from the Django login form to use with the authentication credentials.</p>
<p>Here is the script.</p>
<pre class="qoate-code">
import urllib2
import urllib
import cookielib
from BeautifulSoup import BeautifulSoup

LOGIN_URL = 'http://a-django-site.com/login/'

# for handling cookies to and from all requests we make in this script
# because the site uses cookies for authentication data.
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

# need the CSRF token from the login form that allows us to login
login_form = BeautifulSoup(opener.open(LOGIN_URL).read())
csrf = login_form.find('input', attrs={'name': 'csrfmiddlewaretoken'}).attrMap

# sign in by sending the correct credentials to the login form
credentials = {'username': 'admin',
               'password': '123456',
               'remember': '',
               'csrfmiddlewaretoken': csrf['value']
               }

req = urllib2.Request(LOGIN_URL, urllib.urlencode(credentials))
raw_html = opener.open(req).read()

# test if the login was successful
login_success = 'sessionid' in [c.name for c in cj]
print login_success and 'Login successful' or 'Login failed'
</pre>
<p>Pretty straight forward. Once logged in BeautifulSoup could be used to easily navigate and scrape data from the authenticated web site.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/django/django-site-login-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Improve Django SQL Queries Using Debug Toolbar</title>
		<link>http://tomcoote.co.uk/django/improve-django-sql-queries-using-debug-toolbar/</link>
		<comments>http://tomcoote.co.uk/django/improve-django-sql-queries-using-debug-toolbar/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 21:51:52 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=632</guid>
		<description><![CDATA[
			
				
			
		
Django&#8217;s database querying is there to make life easier but it&#8217;s also easy to forget about the SQL that is still generated under the hood. When using Django&#8217;s query objects it&#8217;s extremely difficult to know how often the database is being hit and with what SQL queries. We often write queries in our views, check [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fimprove-django-sql-queries-using-debug-toolbar%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fimprove-django-sql-queries-using-debug-toolbar%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Django&#8217;s database querying is there to make life easier but it&#8217;s also easy to forget about the SQL that is still generated under the hood. When using Django&#8217;s query objects it&#8217;s extremely difficult to know how often the database is being hit and with what SQL queries. We often write queries in our views, check that they return what we want, then forget them. Lots of the time that is okay but often we&#8217;ll run into performance problems later down the road due to too many database queries. Even if you only have one query in your view, the template might generate more queries without you knowing about them.</p>
<p>Luckily we have the <a href="http://pypi.python.org/pypi/django-debug-toolbar">django debug toolbar</a> to show us how many queries are being sent to our database for a single page request. So I&#8217;m going to go through an example of using the debug toolbar to make a performance improvement for a django view. I&#8217;m not going into how to install the debug tool bar because it&#8217;s all on their download page <a href="http://pypi.python.org/pypi/django-debug-toolbar">here</a>.</p>
<p>I created a simple test site to demonstrate how to find and improve database hits. It has one page which just lists a load of comments from the database. The template HTML is as follows.</p>
<pre class="qoate-code">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Debug Demo&lt;/title&gt;

	&lt;style type="text/css"&gt;
	div {
		margin:10px;
		padding:10px;
		border:1px solid #000;
	}
	&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;h1&gt;Comments&lt;/h1&gt;

	{% for comment in comments %}
	&lt;div&gt;
	&lt;p&gt;Posted by: {{ comment.posted_by.first_name }}&lt;/p&gt;
	&lt;p&gt;Date: {{ comment.post_date|date:"D jS M" }}&lt;/p&gt;

	{{ comment.text|linebreaks }}
	&lt;/div&gt;
	{% endfor %}

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>So as you can see, the template is expecting a list of comments and is just going to create markup to display each of them. The Django model and view are as follows.</p>
<pre class="qoate-code">
from django.db import models
from django.contrib.auth.models import User

class Comment(models.Model):
    post_date = models.DateTimeField(auto_now_add=True)
    posted_by = models.ForeignKey(User)
    text = models.TextField()
</pre>
<pre class="qoate-code">
from django.shortcuts import render
from DebugDemo.models import Comment

def comments(request):

    return render(request, 'comments.html', {
                     'comments': Comment.objects.all()
                    })
</pre>
<p>The result is as expected, the page loads and we see all comments in the database. What you may think by looking at our view code is that one database hit is made, just one that gets all comments. In reality we have one hit to get the comments plus one hit per comment that is retrieved. So to put this in Python form we have len(comments)+1 database hits. The problem is that we won&#8217;t notice a performance problem for this until we have loads of comments to show and loads of visitors wanting to see them. We can see the SQL that was sent to the database by using the debug toolbar and opening the SQL tab. In my example I had two comments in the database so I had three queries as shown below.</p>
<p><img src="http://tomcoote.co.uk/wp-content/uploads/2011/10/debug_toolbar.png" alt="" width="1363" height="351" class="aligncenter size-full wp-image-638" /></p>
<p>What&#8217;s happening here is that the view will run one database query to retrieve all the comment data then our template needs the user&#8217;s name to show against each comment, so when it get&#8217;s to that it will do another query to retrieve each user for each comment. Understanding why these queries are generated is half the battle but it&#8217;s made a lot easier with the debug toolbar as we can see what the SQL is and therefor know what data each is retrieving. When our list of SQL queries has one for comments and loads more for users it&#8217;s pretty obvious what&#8217;s going on. </p>
<p>Solving this is a matter of re-writing our view query so that it retrieves the data that our template needs all at once. To do that we can use the query objects <em>values</em> method. It&#8217;s always about <a href="https://docs.djangoproject.com/en/1.3/topics/db/optimization/#don-t-retrieve-things-you-don-t-need">not retrieving the things you don&#8217;t need</a>. So our new view looks like this.</p>
<pre class="qoate-code">
from django.shortcuts import render
from DebugDemo.models import Comment

def comments(request):

    comments = Comment.objects.all().values('post_date', 'posted_by__first_name', 'text')

    return render(request, 'comments.html', {
                     'comments': comments
                    })
</pre>
<p>You can see that we&#8217;re using the values method to tell Django to only retrieve the three columns that our template needs. The problem now is that our template needs a bit of an update. It currently calls <em>comment.posted_by.first_name</em> to print the users name but this is no longer correct because our new query returns a dictionary of key value pairs not a list of model objects. So here is the new template code, it&#8217;s just using <em>comments.posted_by__first_name</em> instead.</p>
<pre class="qoate-code">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Debug Demo&lt;/title&gt;

	&lt;style type="text/css"&gt;
	div {
		margin:10px;
		padding:10px;
		border:1px solid #000;
	}
	&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;h1&gt;Comments&lt;/h1&gt;

	{% for comment in comments %}
	&lt;div&gt;
	&lt;p&gt;Posted by: {{ comment.posted_by__first_name }}&lt;/p&gt;
	&lt;p&gt;Date: {{ comment.post_date|date:"D jS M" }}&lt;/p&gt;

	{{ comment.text|linebreaks }}
	&lt;/div&gt;
	{% endfor %}

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The result is just one query which we can see in the debug toolbar.</p>
<p><img src="http://tomcoote.co.uk/wp-content/uploads/2011/10/debug_toolbar1.png" alt="" width="1308" height="344" class="aligncenter size-full wp-image-645" /></p>
<p>I hope I&#8217;ve shown how important it is to keep on eye on the queries that are going on because even in this really simple example we can see how performance problems can easily creep in. My advice is to always run through the pages you build with the debug toolbar to have a quick look at the queries to see if there is anything unexpected going on.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/django/improve-django-sql-queries-using-debug-toolbar/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Django Class Based Generic API</title>
		<link>http://tomcoote.co.uk/django/django-class-based-generic-api/</link>
		<comments>http://tomcoote.co.uk/django/django-class-based-generic-api/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 14:06:47 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=582</guid>
		<description><![CDATA[
			
				
			
		
It has been a pretty rainy weekend so I&#8217;ve decided to do some Python programming and have come up with a set of tools to help build API&#8217;s in django. 
I know there are a few libraries already available for building API&#8217;s in django (I&#8217;ve used and contributed to some of them) but since django [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fdjango-class-based-generic-api%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fdjango-class-based-generic-api%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>It has been a pretty rainy weekend so I&#8217;ve decided to do some Python programming and have come up with a set of tools to help build API&#8217;s in <a href="https://docs.djangoproject.com/en/1.3/">django</a>. </p>
<p>I know there are a few libraries already available for building API&#8217;s in django (I&#8217;ve used and contributed to some of them) but since django 1.3 was released with the class based generic views then a lot of the functionality needed to create API&#8217;s is already in the framework. So I decided to just build a few extra things to make API&#8217;s easy in django by using the framework for most of the heavy lifting. </p>
<p>I&#8217;ve made the code available on <a href="https://github.com/cootetom/ClassBasedGenericAPI">GitHub</a>. Here are the features in a nut shell;</p>
<ul>
<li>A new generic class view called APIView which provides a mini framework for supporting different data formats for an API and providing some common API responses. </li>
<li>A throttling decorator to limit API calls per user.</li>
<li>Support for  base64 http authentication.</li>
</ul>
<p>I&#8217;ve put basic support in for JSON requests and responses. The code acts as a good basis for a complete API in django and allows an easy way to extend it for new data formats. It makes good use of POST, GET, PUT and DELETE request methods.</p>
<p><a href="https://github.com/cootetom/ClassBasedGenericAPI">View the repository on GitHub.</a> I would be interested to know how anyone gets on using it and if anyone adds in support for different data formats.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/django/django-class-based-generic-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django South in a team using SVN</title>
		<link>http://tomcoote.co.uk/productivity/django-south-in-a-team-using-svn/</link>
		<comments>http://tomcoote.co.uk/productivity/django-south-in-a-team-using-svn/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 19:57:25 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=343</guid>
		<description><![CDATA[
			
				
			
		
South, the schema and data migration tool for django is really useful. I&#8217;ve only started using it myself recently but the benefit is immediate. South creates python files which hold all the information for migrations each time you change the database schema. Each person in a team of developers needs to run these migrations on [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fproductivity%2Fdjango-south-in-a-team-using-svn%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fproductivity%2Fdjango-south-in-a-team-using-svn%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://south.aeracode.org/" target="_blank">South</a>, the schema and data migration tool for <a href="http://www.djangoproject.com/" target="_blank">django</a> is really useful. I&#8217;ve only started using it myself recently but the benefit is immediate. South creates python files which hold all the information for migrations each time you change the database schema. Each person in a team of developers needs to run these migrations on their development database to keep things up to date and working.</p>
<p>The question is how does one person in a team know that another has changed the schema? If time has passed then simply asking could get a somewhat hazy response.</p>
<p>We use SVN to keep track of code changes amongst the team of developers. SVN is a good place to look to see if migrations were committed. The only thing better than looking in SVN logs for migrations is for SVN to tell us when migrations are committed. So that is what I&#8217;ve had a go at doing.</p>
<p>Using the SVN <a href="http://svnbook.red-bean.com/en/1.0/svn-book.html#svn-ch-5-sect-2.1" target="_blank">pre-commit hook</a> I&#8217;ve been able to send emails to those involved in a project each time someone commits code that contains new database migration changes. The first part of this was to create a pre-commit.bat file in the hooks directory of my projects repository.</p>
<pre class="qoate-code">
C:\python26\python.exe D:\repositories\post_commit_emailer.py %* tom@email.com bob@email.com eddy@email.com
</pre>
<p>This batch file is run by SVN just before a commit happens. It is passed the repository and transaction name when called. As you can see, I&#8217;ve also appended some extra parameters which are the emails of everyone involved with this project.</p>
<p>So the next bit is the python script that this batch file calls.</p>
<pre class="qoate-code">import smtplib
import sys
import pysvn
import re
from datetime import datetime

SERVER = 'localhost'
FROM = 'svn@email.co.uk'
SUBJECT = 'SVN South Migrations Committed'
TEXT = \
'''
The repository location '%s' was committed and included database schema migrations.

Next time you update your working copy for this repository be sure to run the new south migrations on your local database.

The changed files that are thought to be schema migrations are:
   - %s
'''

try:
    # what was committed?
    repo = sys.argv[1]
    txn = sys.argv[2]
    transaction = pysvn.Transaction(repo, txn)
    changes = transaction.changed()

    # look for database migrations that may have been part of this commit
    migrations = []
    for f in changes.keys():
        if re.search(r'migrations/.*\.py$', f):
            migrations.append(f)

    if migrations:
        # prepare the message. Emails to send to are passed as args
        emails = sys.argv[3:]
        message = TEXT % (repo, '\n   - '.join(migrations))
        message = "From: %s\nTo: %s\nSubject: %s\n\n%s" % \
                    (FROM, ', '.join(emails), SUBJECT, message)

        # send the email
        server = smtplib.SMTP(SERVER)
        server.sendmail(FROM, emails, message)
        server.quit()

except Exception as e:
    log = open('C:\\svn_emailer_log.txt', 'a')
    log.write('\n%s : %s' % (datetime.now().isoformat(), str(e)))
    log.close()
</pre>
<p>This script uses <a href="http://pysvn.tigris.org/" target="_blank">pysvn</a> to grab all the changes that are to be committed in this transaction. Once it has that information it looks at the path of each file in the list of changes to find any in a migrations folder. South puts migration files in a folder named migrations. If it finds any then it composes an email to everyone in the parameter list. The email lists the migrations that were committed.</p>
<p>So now everyone involved in a project will get an email if someone commits database schema changes. I&#8217;m going to start using this for our django projects and see how it goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/productivity/django-south-in-a-team-using-svn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Global Django Permissions</title>
		<link>http://tomcoote.co.uk/django/global-django-permissions/</link>
		<comments>http://tomcoote.co.uk/django/global-django-permissions/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 18:20:07 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=322</guid>
		<description><![CDATA[
			
				
			
		
Django has a great solution for web site permissions, it allows the developer to decide how a user can interact with an application based on permissions against models (i.e. database tables). By default a model comes with three permissions, add, change and delete. If these aren&#8217;t enough then you can create as many custom model [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fglobal-django-permissions%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fdjango%2Fglobal-django-permissions%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Django has a great solution for web site permissions, it allows the developer to decide how a user can interact with an application based on permissions against models (i.e. database tables). By default a model comes with three permissions, add, change and delete. If these aren&#8217;t enough then you can create as many custom model based permissions as needed very easily. Infact, this easily:</p>
<pre class="qoate-code">permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)</pre>
<p>This is great but what if your app doesn&#8217;t have a model. Without a model your app doesn&#8217;t get the three default permissions and you can&#8217;t create any custom permissions because you don&#8217;t have the model to base them upon. Well the solution is a simple one but maybe not an obvious one. Django holds two tables for it&#8217;s permissions, one called ContentType and one called Permission. You need to create a new ContentType entry for your app and then add as many entries to the Permission table as you need. The ContentType table has a column for the model name but it&#8217;s just fine to leave that blank.</p>
<p>The next question though is where to put the code to do this job? Ideally it needs to go in a place that is parsed when syncdb is run but not in a place that continually get&#8217;s called as it would have a negative impact on performance. Since the whole point of creating these permissions is because we aren&#8217;t using models, no other part of our app will ever try and import the models file. So the models file is the place to put our code. This file is parsed on syncdb but after that will never be called upon again.</p>
<p>So great, we have the method and we have the place to write the code. All that&#8217;s left is the code itself which is below. We&#8217;re creating one ContentType with the name of our app and then as many Permission&#8217;s as needed, in this case just one!</p>
<pre class="qoate-code">
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_save

def create_app_permissions(sender, **kwargs):
	# create a content type for the app if it doesn't already exist
	ct, created = ContentType.objects.get_or_create(model = '', app_label = 'myappname',
	defaults = {'name': 'myappname'})

	# create a permission if it doesn't already exist
	Permission.objects.get_or_create(codename = 'can_deliver_pizza',
	content_type__pk = ct.id,
	defaults = {'name': 'Can Deliver Pizza', 'content_type': ct})

post_save.connect(create_app_permissions, Permission)
</pre>
<p>One last thing. This code uses signals to run once the Permission model has saved. This means the code won&#8217;t crash when using syncdb with complaints about the Permission or ContentType tables not existing because it won&#8217;t get run until django has created it&#8217;s permissions.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/django/global-django-permissions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django using Eclipse IDE and Pydev</title>
		<link>http://tomcoote.co.uk/productivity/django-using-eclipse-ide-and-pydev/</link>
		<comments>http://tomcoote.co.uk/productivity/django-using-eclipse-ide-and-pydev/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 12:38:44 +0000</pubDate>
		<dc:creator>Tom Coote</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://tomcoote.co.uk/?p=283</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve been using Wingwares python IDE for Django development for almost 2 years. The Wingware IDE has been very good but I have had a few superficial annoyances with it so decided to look around and see what other IDE&#8217;s I could use. This led me to Eclipse. The first time I had a look [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px; margin-top:10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftomcoote.co.uk%2Fproductivity%2Fdjango-using-eclipse-ide-and-pydev%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftomcoote.co.uk%2Fproductivity%2Fdjango-using-eclipse-ide-and-pydev%2F&amp;source=cootetom&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been using <a href="http://www.wingware.com/">Wingwares</a> python IDE for Django development for almost 2 years. The Wingware IDE has been very good but I have had a few superficial annoyances with it so decided to look around and see what other IDE&#8217;s I could use. This led me to <a href="http://www.eclipse.org">Eclipse</a>. The first time I had a look around for Django IDE&#8217;s I remember looking at Eclipse but I think I recall difficulties when trying to run Django projects. Eclipse doesn&#8217;t natively support Django, you have to install Pydev to get that. After revisiting Eclipse and Pydev I can safely say I&#8217;ve switched from Wingware to Eclipse for Django development. The Eclipse IDE in itself is very good and full of useful development features. The Pydev plugin for it which allows python and Django development is also fantastic as it has a GUI for creating and managing Django specific python projects. Another great feature of Eclipse is it&#8217;s free price tag where as a single developer license for Wingware is $179 (roughly £115).</p>
<p>To get my Eclipse set up for Django I installed the following:</p>
<ol>
<li><a href="http://www.eclipse.org/downloads/packages/eclipse-classic-360/heliosr">Eclipse Classic 3.6.0</a></li>
<li><a href="http://pydev.org/download.html">Pydev</a></li>
</ol>
<p>Then I read through and followed a few guides to understand Pydev and Django support:</p>
<ol>
<li><a href="http://pydev.org/manual_101_root.html">Pydev getting started guide</a></li>
<li><a href="http://pydev.org/manual_adv_django.html">Pydev Django integration guide</a></li>
</ol>
<p>In less than an hour I was up and running and fully understood how to start and develop Django projects in Eclipse. I&#8217;d even moved 3 existing Django projects into Eclipse in that time.</p>
<p>Sorry Wingware, you&#8217;ve been good to me but I&#8217;m trying Eclipse for a while and I don&#8217;t think I&#8217;m coming back.</p>
]]></content:encoded>
			<wfw:commentRss>http://tomcoote.co.uk/productivity/django-using-eclipse-ide-and-pydev/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

