Django documentation has been refactored (Changeset 8506) using the excellent Sphinx – Python documentation generator. This is the same package used to generate the new Python documentation Check out the new docs at http://docs.djangoproject.com/. Now I have to go and update all my shortcut snippets. Thanks go especially to Jacob Kaplan-Moss and numerous contributors for all of their hard work on this one.
GitPython Ported to FreeBSD
Wen Heping submitted a port of GitPython to be included with FreeBSD. It has been great to see all the people that have taken interest in GitPython and have worked to support the project.
This Week in Django 30 - 2008-07-20

This Week in Django is a weekly podcast about all things Django.
This week we discuss the NewForms-Admin merge into Trunk, DjangoCon, a few source commits, some cool projects from the community, and the Tip of the Week.
Please see the Show Notes below for all the pertinent information and links
Downloads
AAC Enhanced Podcast (41.8 MB, 49:31, AAC)
MP3 Edition (34.1 MB, 49:31, MP3)
OGG Edition (27.9 MB, 49:31, Vorbis)
The Enhanced Podcast version contains screenshots and easy access links to all of the items we discuss throughout the podcast.
Feeds Available
iTunes Feeds are available. By subscribing using the iTunes feeds the podcasts will automatically be downloaded for you when we release them.
iTunes Feeds
This Week in Django – AAC Edition
This Week in Django – MP3 Edition
Regular RSS Feeds
This Week in Django – AAC Edition
This Week in Django – MP3 Edition
This Week in Django – OGG Edition
Give Us Feedback
Want to give us some feedback on the show? We’re always looking for ideas or suggestions that will help improve each episode. Please contact us at feedback __at__ thisweekindjango.com.
Show Notes
Big News (0:47)
- NewForms-Admin Branch Merges to Trunk – A huge step towards Version 1.0.
- Version 1.0 Sprint Schedule
- NewForms Admin Documentation
- Updated NewForms Documentation
- newforms-admin Migration and Screencast – Great way to get started and make the migration to NewForms-Admin.
- Pre-NFA Merge Tag
- DjangoCon Web Site and DjangoCon Schedule Released – It’s quite a lineup. We hope to see everyone there.
Tracking Trunk (15:04)
- Removed the mysql_old backend
(7949)– According to Malcolm Tredinnick, it smells bad and has no friends.
- newforms -> forms switch
(7971)** django.newforms is now django.forms. Updated your code.
- Performance Improvements for urlize and urlizetrunc filters
(7985)– This one has bit us on the Django Logger.
Community Catchup (26:16)
- Kevin Fricovsky – joins the This Week in Django team as Community Evangelist. Kevin will be working to produce the show, contacting guests, gathering news items, coming up with ideas. Kevin has been doing this work regularly anyway so it’s great of him to team up with us to help out the program:
- Monty Lounge Industries – Kevin’s web strategy, design, and development company.
- How I Work Daily – Kevin’s blog. You should have this one in your feedreader.
- PyWorks conference – to be held in Atlanta, GA on November 12-14, 2008.
- PyOhio – Reminder that this free one day conference is in Columbus, OH on July 26, 2008.
- Twitter Search – via Kevin Fricovsky using the new Twitter Search capability to track all tweets about django.
- Jinja2 Final aka Jinjavitus Released – Armin Ronacher and the rest of the Pocoo team announced the release of this wicked-fast Django inspired template engine.
- OSCON Python BoF – Tuesday, July 22nd 7pm – 10pm from Jax Bar and Restaurant. Via Jason Kirtland’s excellent blog discorporate.
Tip of the Week (38:32)
This tip comes to us via Ben Jao Ming in his post Django auto-translation of field values.
If you need to translate content in a field then gettext is not going to help you out. Since you can create your own custom fields it’s easy to wrap a CharField with the translation behavior:
from django.db import models
from django.utils.translation import gettext_lazy as _
class AutoTranslateField(models.CharField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
return str(_(value))
Just add whatever translations you know of to the locale file and run compilemessages.
Thank You! (42:45)
- 7 Habits For Effective Text Editing 2.0 – Awesome video by Bram Moolenaar
- Brian Rosner
GitPython 0.1.4 Released
I’m pleased to announce the release of GitPython 0.1.4. I appreciate all of the work from contributors on this release, especially from Florian Apolloner who has really taken the lead and managed everything.
DOWNLOAD
You can get it directly from cheeseshop at: http://pypi.python.org/pypi/GitPython/
Or checkout the tag with:
$ git fetch --tags
$ git checkout -b 0.1.4 0.1.4
CHANGES
- renamed
git_pythontogit. Be sure to delete all pyc files before testing.
Commit
- Fixed problem with commit stats not working under all conditions.
Git
- Renamed module to cmd.
- Removed shell escaping completely.
- Added support for
stderr,stdin, andwith_status. git_diris now optional in the constructor forgit.Git. Git now falls back toos.getcwd()whengit_diris not specified.- add a
with_exceptionskeyword argument to git commands.GitCommandErroris raised when the exit status is non-zero. - add support for a
GIT_PYTHON_TRACEenvironment variable.GIT_PYTHON_TRACEallows us to debug GitPython’s usage of git through the use of an environment variable.
Tree
- Fixed up problem where
namedoesn’t exist on root of tree.
Repo
- Corrected problem with creating bare repo. Added
Repo.createalias.
Please let us know if you find problems.
We’re at a point where we have to decide where to go with the library, so if you have ideas, we’d like to know that as well.
Two New Great Books


Hacking Pythons
Someone is very creative. I love it!
“What the hell is going on? This is fucking incredible.” Jacob Kaplan-Moss said. Kaplan-Moss is the chief architect of Django and said nothing like this had ever happened before. “They’re all naked, and these chicks don’t shave anything!”
GitPython
As you’re probably aware of by now, I really like Git. It took some time but things finally started clicking. One of the things I wanted to do was make it easier to interact with Git from Python / Django projects.
I searched around for a Python Git module. I really didn’t find anything that looked complete to me, although I didn’t look too hard. Not being the creative type I noticed that Ruby has the grit library created by Tom Preston-Werner and Chris Wanstrath, which is very nice. I decided to port it because I can use it for some cool stuff, and because I figured it would help me learn a lot about Python. So here it is.
About
GitPython is a python library used to interact with Git repositories.
GitPython is a port of the grit library in Ruby created by Tom Preston-Werner and Chris Wanstrath.
The method_missing stuff was taken from this blog post.
REQUIREMENTS
- Git tested with 1.5.3.7
- Python Nose – used for running the tests
- Mock by Michael Foord – used for tests.
INSTALL
You can download the code from CheeseShop or alternatively pull the source.
python setup.py install
SOURCE
GitPython’s git repo is available on Gitorious, which can be browsed at:
http://gitorious.org/projects/git-python/
and cloned from:
git://gitorious.org/git-python/mainline.git
USAGE
GitPython provides object model access to your git repository. Once you have created a repository object, you can traverse it to find parent commit(s), trees, blobs, etc.
Initialize a Repo object
The first step is to create a Repo object to represent your repository.
>>> from git_python import *
>>> repo = Repo("/Users/mtrier/Development/git-python")
In the above example, the directory /Users/mtrier/Development/git-python
is my working repository and contains the .git directory. You can also
initialize GitPython with a bare repository.
>>> repo = Repo.init_bare("/var/git/git-python.git")
Getting a list of commits
From the Repo object, you can get a list of Commit
objects.
>>> repo.commits()
[<GitPython.Commit "207c0c4418115df0d30820ab1a9acd2ea4bf4431">,
<GitPython.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">,
<GitPython.Commit "e17c7e11aed9e94d2159e549a99b966912ce1091">,
<GitPython.Commit "bd795df2d0e07d10e0298670005c0e9d9a5ed867">]
Called without arguments, Repo.commits returns a list of up to ten commits
reachable by the master branch (starting at the latest commit). You can ask
for commits beginning at a different branch, commit, tag, etc.
>>> repo.commits('mybranch')
>>> repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe')
>>> repo.commits('v0.1')
You can specify the maximum number of commits to return.
>>> repo.commits('master', 100)
If you need paging, you can specify a number of commits to skip.
>>> repo.commits('master', 10, 20)
The above will return commits 21-30 from the commit list.
The Commit object
Commit objects contain information about a specific commit.
>>> head = repo.commits()[0]
>>> head.id
'207c0c4418115df0d30820ab1a9acd2ea4bf4431'
>>> head.parents
[<GitPython.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">]
>>> head.tree
<GitPython.Tree "563413aedbeda425d8d9dcbb744247d0c3e8a0ac">
>>> head.author
<GitPython.Actor "Michael Trier <mtrier@gmail.com>">
>>> head.authored_date
(2008, 5, 7, 5, 0, 56, 2, 128, 0)
>>> head.committer
<GitPython.Actor "Michael Trier <mtrier@gmail.com>">
>>> head.committed_date
(2008, 5, 7, 5, 0, 56, 2, 128, 0)
>>> head.message
'cleaned up a lot of test information. Fixed escaping so it works with subprocess.'
You can traverse a commit’s ancestry by chaining calls to parents.
>>> repo.commits()[0].parents[0].parents[0].parents[0]
The above corresponds to master^^^ or master~3 in git parlance.
The Tree object
A tree records pointers to the contents of a directory. Let’s say you want the root tree of the latest commit on the master branch.
>>> tree = repo.commits()[0].tree
<GitPython.Tree "a006b5b1a8115185a228b7514cdcd46fed90dc92">
>>> tree.id
'a006b5b1a8115185a228b7514cdcd46fed90dc92'
Once you have a tree, you can get the contents.
>>> contents = tree.contents
[<GitPython.Blob "6a91a439ea968bf2f5ce8bb1cd8ddf5bf2cad6c7">,
<GitPython.Blob "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391">,
<GitPython.Tree "eaa0090ec96b054e425603480519e7cf587adfc3">,
<GitPython.Blob "980e72ae16b5378009ba5dfd6772b59fe7ccd2df">]
This tree contains three Blob objects and one Tree object. The trees are
subdirectories and the blobs are files. Trees below the root have additional
attributes.
>>> contents = tree.contents[-2]
<GitPython.Tree "e5445b9db4a9f08d5b4de4e29e61dffda2f386ba">
>>> contents.name
'test'
>>> contents.mode
'040000'
There is a convenience method that allows you to get a named sub-object from a tree.
>>> tree/"lib"
<GitPython.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
You can also get a tree directly from the repository if you know its name.
>>> repo.tree()
<GitPython.Tree "master">
>>> repo.tree("c1c7214dde86f76bc3e18806ac1f47c38b2b7a30")
<GitPython.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
The Blob object
A blob represents a file. Trees often contain blobs.
>>> blob = tree.contents[-1]
<GitPython.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
A blob has certain attributes.
>>> blob.name
'urls.py'
>>> blob.mode
'100644'
>>> blob.mime_type
'text/x-python'
>>> len(blob)
415
You can get the data of a blob as a string.
>>> blob.data
"from django.conf.urls.defaults import *\nfrom django.conf..."
You can also get a blob directly from the repo if you know its name.
>>> repo.blob("b19574431a073333ea09346eafd64e7b1908ef49")
<GitPython.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
What Else?
There is more stuff in there, like the ability to tar or gzip repos, stats, blame, and probably a few other things. Additionally calls to the git instance are handled through a method_missing construct, which makes available any git commands directly, with a nice conversion of Python dicts to command line parameters.
Check the unit tests, they’re pretty exhaustive.
What is Next?
There are a couple of tests that don’t pass due to an inability to mock them properly, so I’m going to get those fixed up.
I also plan to restructure some of the object relationships. A few of them feel a little dirty to me.
LICENSE
New BSD License. See the LICENSE file.
PyCon Badges
If you plan to attend PyCon 2008 in Chicago (and you should plan on it) you can now proudly display PyCon 2008 Badges on your Web site.
Help get the word out. I look forward to seeing you there.
PyCon 2008 Registration Now Open
Carl Karsten (CarlFK) just hoped onto IRC and announced that the PyCon 2008 Registration for Chicago on Friday, March 14, through Sunday, March 16, 2008 is now open.
I registered right away and only experienced one minor problem, which I let CarlFK know about. The site registration email does not contain the correct url. I received:
http:///2008/profile/activate/CODEHERE/??next=/2008/registration/new/
instead of:
http://us.pycon.org/2008/profile/activate/CODEHERE/??next=/2008/registration/new/.
Just fix it up and be on your way. Thanks to all the folks that worked really hard on the new site and to bring the conference together.
One Line Calculator in Python
Rob Crowther just posted on his blog, Dress to Survive, some amazing Python foo that creates a six function calculator in python using some creative regular expression matching and a lambda thrown in for good measure.
>>> print map(...)
5 + 5
3 ^ 2
[10, 9]
I’ll let him divulge all the nitty gritty details. Be sure to check it out at his Web site. He has both the one-liner version and a fully commented version. Pretty darn smart.
XO Has Pippy
I was excited to see that my XO will have Pippy on it. Very cool. Hayden will be coding in Django in no time.
By the way, if you’re looking for a great way to get your hands on some cool technology and benefit a child in a developing country, One Laptop Per Child is extending their Give One Get One program until the end of the year.
PyCon 2007 Talks Available
Looks like some of the PyCon 2007 talks are available for download. I really looking forward to these since I was not able to attend this year.
Age in Years Calculation
Yesterday there was a thread of discussion on the Django Users Google Group about the best way to implement an age in years calculation. The outcome turned out to be quite a creative implementation.
def age(bday, d=datetime.date.today()):
return (d.year - bday.year) - \
int((d.month, d.day) < (bday.month, bday.day))
I modified it ever so slightly. Pretty cool stuff. The real interesting piece is the use of int(). Here if the evaluation is True then int(True) will return 1, meaning we need to subtract a year from the age since the individual’s birthday has not passed yet. Likewise int(False) will return 0. Pretty creative.



