Wordpress and Django: best buddies

Summary: How to integrate a non Django database system in your Django code, using Wordpress as example. The completed code is available at github or you can see some screnshots


Though there are quite a few good Django blog applications, our blog is based on Wordpress. A numberof plugin’s make moving to a Django based app a bad decision for us, and not in the spirit of “best tools for the job”.

We moved the other way, and decided to use Django to admin the Wordpress database. The completed code is available on Github

It is not too hard, with the the builtin Django commands. Django provides the inspectdb command which allows you to build your models.py from an existing non Django database.

Here we will see the steps followed for Wordpress, but it would be about the same for all systems.

TAKE A BACK UP OF WORDPRESS
mysqldump -u wordpress_user -p --database wordpress_database > data.sql 
CREATE A NEW PROJECT, AND SET ITS SETTINGS TO USE THE WORDPRESS DATABASE.
    DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.     DATABASE_NAME = ''             # Or path to database file if using sqlite3.     DATABASE_USER = ''             # Not used with sqlite3.     DATABASE_PASSWORD = ''         # Not used with sqlite3.     DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.     DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3. 
GET THE INITIAL MODELS.PY
./manage.py inspectdb > models.py 

This will create all the database tables in a form Django can understand. Here is what this command creates for a my Wordpress installation with the YARPP plugin. http://gist.github.com/278962

CREATE A NEW APP AND PUT THIS MODELS.PY THERE.

With this done, you can treat the non Django part as a standalone application. Since Wordpress appends all its table with wp_ prefix, we name this applications wp to maintain table name compatibility with Django naming conventions.

You will notice that all models have the db_table populated, so we can rename tables, without changes to the database.

DIFFERENCES BETWEEN WORDPRESS AND DJANGO STYLE NAMING.

At this point you will notice some differences in how Django names things (in a best practice sort of way), and how Wordpress does it.

a. Django table and model class name are (generally) singular. eg class Post(models.Models) leads to table app_post. Wordpress tables are (most of them) named plural eg wp_posts.

b. Django attributes are generally named without the table name part. Eg

class Comment(models.Model):     author_name = models.TextField()     content = models.TextField() 

Wordpress is explicit here and includes the table prefix with attributes.

mysql> desc wp_comments; +----------------------+---------------------+------+-----+---------------------+----------------+ | Field                | Type                | Null | Key | Default             | Extra          | +----------------------+---------------------+------+-----+---------------------+----------------+ | comment_ID           | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |  | comment_post_ID      | bigint(20) unsigned | NO   | MUL | 0                   |                |  | comment_author       | tinytext            | NO   |     | NULL                |                |  | comment_author_email | varchar(100)        | NO   |     |                     |                |   ..... 

I believe this is due to the way you would generally be using the code. In Django you would docomment.author where being explicit doesn’t add any value, while in Wordpress, you would use, select comment_author, post_title ... from wp_comment, wp_post ... where join, where being explicit is useful.

You can decouple the Django and database names by using the db_table and db_column attributes. We choose to rename the Class names to match Django conventions while we let the column names remain the same.

ADD ADMIN AND OTHER DJANGO NICETIES.

Wordpress doesn’t (seem to) have foreign key constraints setup correctly, and uses bigint(20) unsigned without foreign key constraints to refer to referred entities. This means Django creates all ForeignKeys as IntegerFields.

Modify them to use ForeignKey instead. Also add __unicode__, to your classes.

Add an admin.py to register all your classes.

And you are done! Now you can access, and work with your Wordpress data inside Django and Django admin.


There are a few more things which will allow a easier Wordpress setup.

CREATE TEMPLATE TAGS TO SHOW THE LATEST POSTS AND COMMENTS.
@register.inclusion_tag("wp/recent_posts.html") def show_posts(num_comments):     return {"posts": Post.objects.filter(post_type="post", post_status="publish").order_by("-post_date")[:num_comments]} 

So you can see that there is nothing Wordpress specific we need too do here.

CREATE A BETTER ADMIN.
Add ModelAdmin to generally used models. 
ALLOWS ACCESSING ATTRIBUTES VIA THE DJANGO STYLE NAMES.

If you override __getattr__, you can access the attributes via other names. Eg in the current setup you need to do comment.comment_content, comment.comment_author etc, while we would like to docomment.content and comment.author as a shortcut.

class WordPressModel(object):         def __getattr__(self, v):         if v in self.__dict__:             return self.__dict__[v]         else:             new_v = "%s_%s" % (self.__class__.__name__.lower(),  v)             if new_v in self.__dict__:                 return self.__dict__[new_v]             else:                 raise AttributeError 

It is highly debatable whether this is a good idea :) , but it is too convenient right now not to test this method out.

Here are some screenshots.


Do you subscribe to our feed? We recently made a full text feed available, so if you are using the old feed, you should change it. Subscribe now.

Django 1.2 release schedule - Update 3

Another good week of progress towards the 1.2 release milestone. We are now down to 54 open tickets, of which 28 are documentation or translation updates that can be addressed after the release candidate lands. This leaves 26 substantive tickets before we have a release candidate.

Although we've been reducing the ticket count by 20-30 tickets per week, some of the progress this week was due to a purge of tickets that were not critical to the 1.2 release. This means we have really had a slight slowdown in progress over the last week. This isn't entirely surprising; as we get closer to the release candidate, the complexity of the tickets that remain tends to increase, as the difficult tickets usually get left until last.

When this slowdown is combined with the fact that this weekend covers the Easter break, it's unlikely we're going to squash all 25 RC-blocking bugs by April 5. Therefore, we're going to push back the RC date by another 2 weeks. This means we are now targeting a release candidate around April 19, with a final release around April 26.

As always -- any and all assistance is most welcome; the more assistance we get, the faster 1.2 will land.


Source: http://www.djangoproject.com/weblog/2010/apr/01/django-1_2-release-schedule-update-3/

Rails and Django commands : comparison and conversion

The most commonly used Rails commands and their Django equivalents

RailsDjango
rails consolemanage.py shell
rails servermanage.py runserver
rakeNone
rails generateNone
rails dbconsolemanage.py dbshell
rails app_namedjango-admin.py startproject/manage.py startapp
rake db:createmanage.py syncdb

The salient points to note are,

  1. Django has all commands via manage.py, Rails has it broken into rails and rake.
  2. Overall there are more Rails+Rake commands available than Django commands
  3. There is no one to one mapping between Rails and Django commands. Eg. There are no equivalent to rake doc:* or rake notes in Django.

Similarly there is no equivalent to manage.py createsuperuser in rails.

References

http://docs.djangoproject.com/en/dev/ref/django-admin/http://guides.rails.info/command_line.html http://github.com/uswaretech/Acts-as-Django/blob/master/commands.markdown

Tools of Pro Django developer – aka What powers dinette and almost every app we write.

There are some tools and apps which we use with almost all apps we write, and in particular which, we used for dinette. Here they are broken into useful during development, and (also) useful post development.

During Development

  1. Ipython and ipdb
  2. South
  3. Django test utils
  4. Django extensions
  5. Django debug toolbar
IPYTHON AND IPDB

Ipython is a enhanced shell for python. Ipdb similarly add extra capacity to the builtin pdb debugger. It is extremely convenient to drop into a ipython shell right where a complex piece of code is being hit.

from IPython.Shell import IPShellEmbed ipython = IPShellEmbed() ipython() 

Of course this does not allow you to step through, so if you want to step through your code, you need to do

import ipdb ipdb.set_trace() 

Of course, you can just do pdb.set_trace(), but with tab completion and syntax highlighting, using ipdb is a no brainer.

SOUTH

South adds schema migration to Django. It has lot of advanced options, but just three command will get you along way.

Convert a normal app to use the south way.

./manage.py convert_to_south 

Once you have made any changes to your apps model, write a new migration which can update the database to latest models.py

./manage.py startmigration appname nameofmigration --auto 

Once you have written a migration, write a command to update the db.

./manage.py migrate appanme  
DJANGO TEST UTILS

When you are running tests, a huge time sink is the time spent dropping and recreating tests. You might add just a single test, and the default Django testrunner will spend a huge time recreating the database. Enter manage.py quicktest which reuses databases between test runs. One of the side effects of this is that if you modify models.py between test runs you should manually recreate the database.

The tests (or whatever little of it exists) for Dinette were written using testutils’ testmaker.

DJANGO EXTENSIONS

Django extensions, (earlier Django command extensions) is a app which adds extra commands tomanage.py. It has lot of goodies, but just ./manage.py shell_plus makes it worthwhile. (It imports all the models from all the apps automatically).

Get the full list at Github

DJANGO DEBUG TOOLBAR

I do not personally use it but some people on our team swear by it.

After development

  1. Django-pagination
  2. sorl-thumbnails
  3. django-compressor
  4. Haystack
DJANGO-PAGINATION

I have decided on a standard way to build apps which need pagination. a. Build apps without pagination. b. The night before release spend an hour and add pagination to all pages. Really this is all you need

{% load pagination tags %} {% autopaginate queryset %} .... {% paginate %} 

There is no change required to the views.

SORL-THUMBNAILS

To thumbnail an image.

{% thumbnail image size %} 

“Things should be as simple as possible, but not simpler.”

DJANGO-COMPRESSOR

During development we work with multiple unminified js and css files. Django-compressor takes care of minifying and compressing it when we deploy. All we need to do is,

{% compress css %} ... all css files .... {% endcompress %}   {% compress js %} ... all js files .... {% endcompress %} 
HAYSTACK

Haystack is “modular search for Django”. It make writing search views as easy as writing the admin. You declaratively tell what fields you want to search on, and Haystack can take care of creating and updating the index, and providing a generic view to handle the search. Check a search view written using Haystack http://uswaretech.com/forum/search/?q=django


To everyone who contributed to these apps, thanks. Django development won’t be the same without these great tools. This post was inspired by Kevin Fricovsky’s post post, The apps that power Django-Mingus and is stolen about 50% from there. Thanks. :)

The coolest forum apps based on Django

1. Django-forum by Uswaretech:

twitter ready version:

We have released a Django forum application, with some cool features not in any other Django based forum. You can get it here or see it in action.

blog version

There are quite a few Django based forum applications, so why another? Its a bit of a rhetorical question, as the answer is “none of them met my needs exactly, so we created my own”, as you might expect.

Without further ado here is a list of features. It is available on uswaretech.com/forum/.

  • Based on, inspired by and ripped from PunBB. (Thanks!)
  • PunBB like 3 phased hierarchy [Forum]->Subforum->Topic->Post
  • Tightly integrated with Socialauth. (Screenshots)
  • Gravatar support
  • Moderation features (Close, stikify, make announcement etc.)
  • Ajax based posting

We are starting our forums based on this app, so we plan to be supporting and developing this for foreseeable future. Fork this on Github or check this out now.

Screenshots

Main page

2. PyBB: (http://pybb.org/)

PyBB (Python Bulletin Board) is a python forum engine implemented as django application. The aim of PyBB development is to build django application which could be easily built in existing django project.


This is a basic forum component that can plug into any existing Django installation and use it's existing templates, users, and admin interface. Perfect for adding forum functionality to an existing website.

Current Status

  • Uses Django Admin for maintenance / moderation - no in-line admin features as yet
  • Uses existing django Auth and assumes you already have that up and running. I use and recommend django-registration
  • Roll your own site with little work: Install Django, install django-registration, flatpages, django-forum, setup your templates and you have an instant website :)
  • Code is as pulled out of my other projects - changes will be made as I go to make sure it's as standalone as possible, right now should be pretty good.


4. DjangoBB: (http://djangobb.org/)

DjangoBB is a quick and simple forum which uses the Django Framework (written in Python language). Abbreviation DjangoBB stands for Django Bulletin Board. DjangoBB is distributed under the BSD license.

The basic concept of the forum progress is:

  • the usage of various DBMS (MySQL, PostgreSQL, Oracle, SQLite)
  • the ease of integration into any Django project and the ease of installation
  • the usage of standard libraries for launching on conventional hostings with python support
  • user-friendly installation process
  • classic view of the forum like IPB, PhpBB, Punbb
  • easy forum setup
  • high speed
  • reliability

At the current stage of development the main object is the functional implementation of the PunBB forum, in the sequel it is projected to expand it significantly.

(by The Django Bay 2010) - DjangoBay.com