Django Generic Class Based View Tip

Those reading this via a feed reader will have to view the page on my blog as I am using embedded gists. I’ll find a solution for that in the future.

So say you have a base template that looks something like:

And a template that looks like either of these:

It used to be that you could write something like this:

But generic function based views are deprecated and the world is being strongly urged to move to generic class based views. If you would like to get extra_content working with the direct_to_template replacement TemplateView, you can use a view like the following:

And a urls.py like the following using it:

The code used in this blog post can be found in this gist.

Being a Contributor

When I attended DjangoCon I decided I needed to work a bit less on my own projects and start putting more time into contributing to other projects. I use so many free and open libraries both in my work and my personal code, and it is time to start contributing again.

The first project I decided to try to contribute to was Read the Docs. The choice was pretty easy since I know Eric Holscher and it is a project I benefit from on a regular basis. So at the DjangoCon sprints I sat down near him and asked him if there were any particularly valuable tickets I could take and start hacking on. He gave me a list of issues and I started in.

By the end of the day I had a patch for RTD, granted it didn’t fully work but it was a start. Added some unit tests and fixed up the code and soon I had a complete contribution that was added and it made me smile. And smile even more to be added to the AUTHORS file. Couple more patches later and Eric asked if I wanted to help out with the servers and get access to them. I said yes and now I am part of the RTD ops team as well as a contributor.

I used to contribute to a couple projects a few years ago. In recent history I’ve spent my time scratching my own itches and working on proprietary code for work. Going through the process of contributing has made me excited to do it some more on various projects. And GitHub makes it so easy to just send a pull request, comment a couple times back and forth and get patches accepted.

I am far from the first to talk about how easy it is to contribute to projects compared to the old days of sending patches to mailing lists. I just want to be another voice in the crowd, if even one person decides to contribute because of this, or it makes a person happy and continues contributing this was a success.

Django, Redmine both on the same vhost in apache

I’ve spent a good portion of my day messing with this, asking questions in various channels on irc.freenode.net, and generally trying to not let my head explode.

What ‘this’ is exactly is this:

I wanted my django app to run on / of my domain. Since I don’t own my domain it would be easiest(or so I thought) to setup redmine on /redmine of my domain. This way it is only one domain and I can run my bug/project tracker on the same place as my website.

http://synput.thruhere.net
http://synput.thruhere.net/redmine

That shows that I have it all working, now how did I do it… It will be simple for you but was not a simple process for me due to a couple settings I had tweaked without realizing the effect.

First off lets get the django app setup, I use mod_wsgi for my django apps, and run them in daemon mode so I can easily update the app without taking down the server at all.

My wsgi file (should look pretty typical for those who have seen one before):

import os
import sys

root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(root_dir)

os.environ['DJANGO_SETTINGS_MODULE'] = 'recipes.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

You’ll need to toss

LoadModule wsgi_module modules/mod_wsgi.so

into your httpd.conf

Here is my vhost stuff without the Redmine stuff in it:

<virtualhost 80="">
ServerName synput.thruhere.net
ServerAdmin xwraithanx@gmail.com

Alias /media /srv/wsgi/recipes/media

<directory srv="" wsgi="" recipes="" media="">
Order allow,deny
Options Indexes FollowSymlinks
Allow from all
</directory>

WSGIDaemonProcess recipes python-path=/srv/wsgi/recipes/lib/python2.6/site-packages display-name=%{GROUP}
WSGIProcessGroup recipes
WSGIScriptAlias / /srv/wsgi/recipes/recipes.wsgi

<directory srv="" wsgi="" recipes="">
Order deny,allow
Allow from all
</directory>
</virtualhost>

So far this should look pretty typical for anyone who has ever setup a django vhost with apache.

Now for Redmine I chose to use Phusion, why you might ask? Well sycopomp uses it and when I asked him why, because he found a guide somewhere that made it easy and his memory usage isn’t very high. So basically, not for any good reason.

Go ahead and symlink your redmine/public directory into your DocumentRoot for me that was /srv/http.

You’ll have to install Phusion:

gem install passenger
passenger-install-apache2-module

That will toss up a helpful wizard to do the installation for you with a couple of prompts. You will need to copy the lines from the wizard into your httpd.conf, they should look something like:

LoadModule passenger_module /usr/lib/ruby/gems/1.9.1/gems/passenger-2.2.9/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.9.1/gems/passenger-2.2.9
PassengerRuby /usr/bin/ruby

Next we need to add a line to our vhost and change another one, first line we’ll add tells the server where to find and put redmine:

RailsBaseURI /redmine

And secondly we need to change out:

WSGIScriptAlias / /srv/wsgi/recipes/recipes.wsgi

Add put in the following instead since that will make django not catch /redmine:

WSGIScriptAliasMatch ^\/(?!redmine(.*)) /srv/wsgi/recipes/recipes.wsgi

Restart the server and we should be good.

I didn’t make this page/code as generic as I could have but hopefully you can get the meaning from it, if not the kind folks in #httpd on irc.freenode.net can help you. They’ll understand this if you don’t. Also, do what some like to call frobbing, play with it, break it, whatever it takes so you understand it.

bpython and django

There are a few posts out there to get basic support for django inside of bpython but I as far as I have seen they ignore the virtualenv stuff that most of us django users do.

virtualenv is a must when doing development on django projects, especially when you have several projects going on the same machine or you want to involve other developers. It allows for a clean environment with known versions of every package that is installed inside of the virtualenv.

The first part of this is a known hack or method (take your pick) to make bpython recognize the django project.

First you need to modify your ~/.bashrc or ~/.bash_profile (system dependent as to which is used) and add the following line to it:

export PYTHONSTARTUP=~/.pythonrc

What this does is it tells python to run ‘~/.pythonrc’ before it does anything else in the interpreter, this is a python specific thing not bpython specific thing.

Next you need to create the ~/.pythonrc file and put the following into it:

try:
   from django.core.management import setup_environ
   import settings
   setup_environ(settings)
except:
   pass

Now if we didn’t care about virtualenv we’d be completely done. If you go the less strict route and don’t use –no-site-packages (the switch means that system wide packages are to be ignored in the virtualenv) then you will need to edit your bpython binary, most commonly located at /usr/bin/bpython or /usr/local/bin/bpython and change the shebang from:

#!/usr/bin/python

(it may be /usr/local/bin/python)
to:

#!/usr/bin/env python

This makes bpython use the value of the environment variable python instead of using a specific binary, the environment variable gets set by virtualenv so you are good to go after this.

If you use –no-site-packages then you will have to install bpython in each virtualenv that you want to use it in.

If you have any questions toss them in the comments or find me on freenode as Wraithan.