Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Twitter user timeline with a Django templatetag
A simple templatetag for adding to the template context a variable with the user timeline from Twitter. It uses the CachedContextUpdatingNode snippet for caching from Jacob Kaplan-Moss. The reason that is necessary to cache content is because Twitter limits the number of accesses to the API. This only works if the cache is enabled on your settings.py. class TwitterNode(CachedContextUpdatingNode): cache_timeout = 1800 # 30 Minutes, maybe you want to change this def __init__(self, username, varname): self.username = username self.varname = varname def make_datetime(self, created_at): return datetime.fromtimestamp(mktime(strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'))) def get_cache_key(self, context): return 'twitter_user_timeline_cache' def get_content(self, context): try: response = urllib.urlopen('http://twitter.com/statuses/user_timeline/%s.json' % self.username).read() json = simplejson.loads(response) except: return {self.varname : None} for i in range(len(json)): json[i]['created_at'] = self.make_datetime(json[i]['created_at']) return {self.varname : json} @register.tag def twitter_user_timeline(parser, token): bits = token.contents.split() if len(bits) != 4: raise TemplateSyntaxError, "twitter_user_timeline tag takes exactly three arguments" if bits[2] != 'as': raise TemplateSyntaxError, "second argument to twitter_user_timeline tag must be 'as'" return TwitterNode(bits[1], bits[3]) Usage: {% twitter_user_timeline username as twitter_entries %} {% if twitter_entries %} {% for entry in twitter_entries %} {{ entry.created_at|date:"d M Y H:i" }} - {{ entry.text }} {% endfor %} {% endif %} Use the source, Luke. -
Twitter user timeline with a Django templatetag
A simple templatetag for adding to the template context a variable with the user timeline from Twitter. It uses the CachedContextUpdatingNode snippet for caching from Jacob Kaplan-Moss. The reason that is necessary to cache content is because Twitter limits the number of accesses to the API. This only works if the cache is enabled on your settings.py. class TwitterNode(CachedContextUpdatingNode): cache_timeout = 1800 # 30 Minutes, maybe you want to change this def __init__(self, username, varname): self.username = username self.varname = varname def make_datetime(self, created_at): return datetime.fromtimestamp(mktime(strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'))) def get_cache_key(self, context): return 'twitter_user_timeline_cache' def get_content(self, context): try: response = urllib.urlopen('http://twitter.com/statuses/user_timeline/%s.json' % self.username).read() json = simplejson.loads(response) except: return {self.varname : None} for i in range(len(json)): json[i]['created_at'] = self.make_datetime(json[i]['created_at']) return {self.varname : json} @register.tag def twitter_user_timeline(parser, token): bits = token.contents.split() if len(bits) != 4: raise TemplateSyntaxError, "twitter_user_timeline tag takes exactly three arguments" if bits[2] != 'as': raise TemplateSyntaxError, "second argument to twitter_user_timeline tag must be 'as'" return TwitterNode(bits[1], bits[3]) Usage: {% twitter_user_timeline username as twitter_entries %} {% if twitter_entries %} {% for entry in twitter_entries %} {{ entry.created_at|date:"d M Y H:i" }} - {{ entry.text }} {% endfor %} {% endif %} Use the source, Luke. -
OpenCalais beats me to the punch
I've been playing with various entity and information extraction frameworks for the past couple weeks with the goal of creating an web service for extracting the major topics from news articles. SP far, my work, such that it is, has shown promise, but is not as robust or reliable as I would have hoped. I just noticed that Reuters has apparantly been working along the same lines and have opened their work to the public. On the one hand, I feel beaten. On the other, their service does not appear to be much better than my own - although they'll have a larger set of people re-training their decision trees than I'll ever have. I've been using posts from my own blog as my testing ground, so I thought I'd throw my last post through and see what it churns out: Relations: PersonProfessional Organization: Entrepreneur Fund IndustryTerm: rubber Person: Len Gilbert, Tom Berreca, Darline Jean, Glenn Franxman, Matthew de Gannon, Sam Parker, Clark, Beth Higbee, Eleanor Cippel, Martha Stewart City: Naples Well, I don't even try to extract relations, so that's pretty cool. IndustryTerm is pretty puzzling, although I understand why they were fooled by it. My organization extraction appears … -
Overdue Catchup
I've had a very busy few months in every way conceivable - everything from my Django projects, to my day job, to life as a whole has been running in fast-forward. Here's a quick summary of the DjangoSites is coming along very well, with 1040 sites listed as of this evening. The quantity and quality is ever-increasing, and more and more sites are being claimed. There are still well over 300 unclaimed sites - is yours listed there? If so, drop an email with your DjangoSites username to djangosites@djangosites.org. After a server move late last year my Django OpenID project went offline for a little while. After a handful of requests from the blogosphere I've put it back online - see my original blog posting on the topic for more details, although I'm guessing that Simon Willison has something up his sleeve that'll trump my hack-job soon enougy. Over my Christmas holidays I launched Jutda, the 'corporate' face for my upcoming web projects built with Django. The word Jutda is from the Wagiman language, a dialect spoken by an ever-shrinking Aboriginal tribe in the Northern Territory of Australia. It means show the way, which is something I hope to do … -
Overdue Catchup
I've had a very busy few months in every way conceivable - everything from my Django projects, to my day job, to life as a whole has been running in fast-forward. Here's a quick summary of the DjangoSites is coming along very well, with 1040 sites listed as of this evening … -
Starting in with ReviewBoard
I’ve been meaning to dive into the project ReviewBoard since I first heard about it, many months ago. I had first heard of a similar critter – Google’s internal tool called Mondrian. I was pretty darn excited about that tool … Continue reading → -
Django on Ubuntu 7.10 (gutsy)
I slapped together a virtual machine to try out an instance of ReviewBoard. It’s been a little while since I fiddled with Ubuntu, so I grabbed the latest server release(7.10) and set it up. Then I settled in to get … Continue reading → -
A Mercurial mirror of Django's Subversion repository
Just wanted to post a quick note that I'm now publishing an experimental Mercurial mirror of the Django source code repository, including all tags and branches and even the djangoproject.com website source itself. Tom Tobin at The Onion has been maintaining a similar mirror of Django trunk for a while (and very helpfully answered some of my questions in IRC), but I wanted to do the whole tree. It's an experiment, which is to say it might go away at any time, so be warned! And let me know if you think it's useful. Components in the chain include svnsync, hgwebdir, Apache mod_cache, and even Pygments for source code colorizing. It's updated once per hour. My earlier experiments along these lines used hgsvn, which is cool because it tags each commit with the corresponding svn rev number. Unfortunately, hgsvn basically ground to a halt while trying to digest all 7000 revs, so I switched to Mercurial's built-in "convert" command. Mercurial doesn't yet support partial-tree cloning, so if you want your own copy you're going to be fetching the whole thing! It takes up about 350MB, which isn't bad considering it includes all 7000+ changesets. Have fun! http://hg.dpaste.com/django/ Update: I've replaced … -
New Projects
In the past couple weeks my curiosity has inspired me to create several new projects. Some are useful, others are simply proof-of-concept. Written in a variety of languages—Javascript, Python and Ruby—the following programs are works in progress. Please try them out and let me know what you think. -
Covering Kansas Democratic Caucus Results
I think we’re about ready for caucus results to start coming in. We’re covering the Caucus results at LJWorld.com and on Twitter. Turnout is extremely heavy. So much so that they had to split one of the caucus sites in two because the venue was full. Later… How did we do it? We gained access to the media results page from the Kansas Democratic Party on Friday afternoon. On Sunday night I started writing a scraper/importer using BeautifulSoup and rouging out the Django models to represent the caucus data. I spent Monday refining the models, helper functions, and front-end hooks that our designers would need to visualize the data. Monday night and in to Tuesday morning was spent finishing off the importer script, exploring Google Charts, and making sure that Ben and Christian had everything they needed. After a few hours of sleep, most of the morning was spent testing everything out on our staging server, fixing bugs, and improving performance. By early afternon Ben was wrapping up KTKA and Christian was still tweaking his design in Photoshop. Somewhere between 1 and 2 p.m. he started coding it up and pretty soon we had our results page running on test … -
I Want to Move My Blog to Django
Oh how I long to move this blog off of WordPress and onto something I build (or cull together) on top of the Django platform. It feels like it is mostly pulling together a host of different apps that are already written: django-tagging Comments Comment Utils django-pingback Markup Syndication That leaves a core part of the blog to write -- something to store the actual entries and then a URL scheme to display different levels of archives and individual posts. Of course, this schemes needs not to break current links. This led me to check out what already might exist on Google Code and found these (limited to the most active): waggly-blog blogmaker django-basic-blog django-diario blogango All are basically the same, with slightly different inclusions and approaches to this core "Blog" feature. Lastly, a feature I'd want to implement (if there isn't already an app out there supporting it that I can integrate) is a MetaWeblog API interface so that I can use MarsEdit, my favorite blog publish. Then all that would be left would be figuring out the data structure of WordPress and migrate over all my content (this is the only part that I am not looking forward … -
I Want to Move My Blog to Django
Oh how I long to move this blog off of WordPress and onto something I build (or cull together) on top of the Django platform. It feels like it is mostly pulling together a host of different apps that are already written: django-tagging Comments Comment Utils django-pingback Markup Syndication That leaves a core part of the blog to write -- something to store the actual entries and then a URL scheme to display different levels of archives and individual posts. Of course, this schemes needs not to break current links. This led me to check out what already might exist on Google Code and found these (limited to the most active): waggly-blog blogmaker django-basic-blog django-diario blogango All are basically the same, with slightly different inclusions and approaches to this core "Blog" feature. Lastly, a feature I'd want to implement (if there isn't already an app out there supporting it that I can integrate) is a MetaWeblog API interface so that I can use MarsEdit, my favorite blog publish. Then all that would be left would be figuring out the data structure of WordPress and migrate over all my content (this is the only part that I am not looking forward … -
A picture is worth a thousand words
Paul Graham: Arc only supports Ascii. MzScheme, which the current version of Arc compiles to, has some more advanced plan for dealing with characters. But it would probably have taken me a couple days to figure out how to interact with it, and I don’t want to spend even one day dealing with character sets. Character sets are a black hole. I realize that supporting only Ascii is uninternational to a point that’s almost offensive […] But the kind of people who would be offended by that wouldn’t like Arc anyway. -
Django People Rocks
This is a really cool site for getting a sense for the django community in your community. I just put my profile up. We need a micro-format (maybe hcard would work) for "profiles" so the same set of metadata about ourselves can just be reused at the different "profile sites" that we find ourselves joining. -
Django People Rocks
This is a really cool site for getting a sense for the django community in your community. I just put my profile up. We need a micro-format (maybe hcard would work) for "profiles" so the same set of metadata about ourselves can just be reused at the different "profile sites" that we find ourselves joining. -
Breaking Apart Models in Django
Depending on the size of your models.py, you may find it becoming unwieldy, especially if you are on a team with multiple developers are editing the same file, increasing the odds for merge conflicts. There are two parts to breaking up a large module in Django. The first is a purely Python convention where you break apart the file into multiple files and create a subdirectory for the name of the original module so your models.py file becomes: models/__init__.py models/module1.py models/modlue2.py Inside your __init__.py you'll want to import from your module1.py and module2.py modules and add those imported objects to __all__: # __init__.py from app.models.module1 import MyClass from app.models.module2 import AnotherClass, function_one __all__ = ['MyClass', 'AnotherClass', 'function_one'] Now that you have taken care of the Python part of this exercise, you'll need to do a couple tricks to get your models importing properly in the context of your django project. It involves adding a couple o attributes to the Meta inner class. Thanks to Collin Grady (aka Magus on #django on irc.freenode.net) for pointing these tips out to me: class MyClass: ... class Meta: app_name = 'myappname' db_table = 'myappname_myclass' Now you should have a better code base that causes … -
Breaking Apart Models in Django
Depending on the size of your models.py, you may find it becoming unwieldy, especially if you are on a team with multiple developers are editing the same file, increasing the odds for merge conflicts. There are two parts to breaking up a large module in Django. The first is a purely Python convention where you break apart the file into multiple files and create a subdirectory for the name of the original module so your models.py file becomes: models/__init__.py models/module1.py models/modlue2.py Inside your __init__.py you'll want to import from your module1.py and module2.py modules and add those imported objects to __all__: # __init__.py from app.models.module1 import MyClass from app.models.module2 import AnotherClass, function_one __all__ = ['MyClass', 'AnotherClass', 'function_one'] Now that you have taken care of the Python part of this exercise, you'll need to do a couple tricks to get your models importing properly in the context of your django project. It involves adding a couple o attributes to the Meta inner class. Thanks to Collin Grady (aka Magus on #django on irc.freenode.net) for pointing these tips out to me: class MyClass: ... class Meta: app_name = 'myappname' db_table = 'myappname_myclass' Now you should have a better code base that causes … -
Breaking Apart Models in Django
Depending on the size of your models.py, you may find it becoming unwieldy, especially if you are on a team with multiple developers are editing the same file, increasing the odds for merge conflicts. There are two parts to breaking up a large module in Django. The first is a purely Python convention where you break apart the file into multiple files and create a subdirectory for the name of the original module so your models.py file becomes: models/__init__.py models/module1.py models/modlue2.py Inside your __init__.py you'll want to import from your module1.py and module2.py modules and add those imported objects to __all__: # __init__.py from app.models.module1 import MyClass from app.models.module2 import AnotherClass, function_one __all__ = ['MyClass', 'AnotherClass', 'function_one'] Now that you have taken care of the Python part of this exercise, you'll need to do a couple tricks to get your models importing properly in the context of your django project. It involves adding a couple o attributes to the Meta inner class. Thanks to Collin Grady (aka Magus on #django on irc.freenode.net) for pointing these tips out to me: class MyClass: ... class Meta: app_name = 'myappname' db_table = 'myappname_myclass' Now you should have a better code base that causes … -
Comment Spam Stats
Since January 12th: Valid comments accepted by Akismet: 36 Spam comments accepted by Akismet: 17 Spam comments rejected by Akismet: 814 I don't have a number for false positives, but given that I've received zero email complaints I'll assume the number is low if not zero. This gives Akismet about a 98% success rate on catching spam, which is pretty good. It makes my life better. Having more spam comments than real comments get through the gates can be really depressing for a blog owner. At some point I'll post my Django newforms/Akismet integration code. It's very simple, and clearly worth the effort. Update: James Bennett reminds me that his comment_utils wrap up anti-spam and comment moderation measures in one tidy package. -
Shameless self-promotion
I’ve got a couple of sweet upcoming speaking/teaching gigs coming up, and now I’m going to pimp them out. If you’re not down with self-promotion, you should read no further. February 22-23 I’ll be speaking at Journalism 3G, a symposium on technology and journalism at Georgia Tech. I’ll be part of a roadmaps session wherein I get to pontificate about the future of journalism and the cool tech on the horizon. -
Working around MySQL’s horrible “ORDER BY rand()” in Django
Recently I’ve been working on a web 2.0ish community site written in Django. As is frequently the case with such sites I often need to create lists or collections of psuedo-randomly selected items. For example on a user’s profile page there may be a box showing a few of the user’s friends, another box with [...] -
We Are Django
I've always thought that the community is one of the greatest things about Django. Not because Django isn't great but because the people are just so awesome! [Django People](http://djangopeople.net/) is a brilliant new site by [Simon Willison](http://simonwillison.net/) and [Natalie Downe](http://notes.natbat.net/) which brings together Djangonauts all over the world. <small>(Interestingly, I was talking about _exactly_ this same idea yesterday with my friend, in the lines of "there should definitely be something like that". Great minds think alike (I wish) :)</small> I had the pleasure of meeting Simon and Natalie during the Europython conference [last summer](/en/hoyci/2007/07/europython-2007/). Like every other Django people at the conference, they were super-nice and fun to share thoughts with. The various conversations we had with the Web-gang there were definitely one of the highlights of my last year. I hope that Django People will help in finding more same-minded people, both near you and when traveling around the world. If you are Djangonaut, add yourself to the site! And when you do, please include your picture and some information about yourself. It's so much nicer to look at real faces than empty rectangles :) Here's to many more Django friends. -
We’re hiring!
Wow, the Django job market is heating up. I posted a job opening for both junior and senior-level Django developers on djangogigs just a few days ago, and it has already fallen off the front page. So I’ll mention it again: We’re hiring! We’re growing and we have several positions open at both the junior and senior level. We’d love to talk to you if you’ve been working with Django since back in the day when everything was a tuple. We’d love to talk to you if you’re smart and talented but don’t have a lot of (or any) Django experience. Definitely check out the listing at djangogigs for more, or feel free to drop me a line if you’d like to know more. -
django-validation now includes inheritance support
I’m happy to announce django-validation got field type inheritance support since a couple of minutes. This means your form fields will be validated starting from the most base field type (django.newforms.Field) up to the actual field type (no multiple-inheritance supported though). In the example I wrote yesterday, when using a TestField field, this field will be validated as a django.newforms.Field (a “required” check will be done), then as a django.newforms.CharField (“min_length” and “max_length” checks), and finally as a TestField. A normal CharField would be validated as a Field first, then as a CharField, etc. The returned errors will be a list of all errors found, starting with the most basic one (the ones found by the most general class, Field). Next to this, all generated Javascript code should be namespaced now (based on Python module and class names), although there might be some bad things left, I’m no Javascript guru. The generated code might be somewhat messy. Current Python code is most certainly ugly and will need more rewrites. Next to this, other field types should be added, and some tests would be nice too. I made a snapshot of yesterday’s sample (with some changes, the ClientValidator API slightly changed), … -
Deploying Compacted Javascript with Django
Here is a small extension to the manage command to make deployment of compacted javascript easier (hopefully). I think this is better explained with a usage example. I have the templates referring both the standard javascript files for easier debugging and compacted ones for deployment (the debug variable is the standard one and allows the split between development/deployment). {% if debug %} <script src="{{ MEDIA_URL }}js/jquery-1.2.2b.js" type="text/javascript"></script> <script src="{{ MEDIA_URL }}js/jquery.cookie.js" type="text/javascript"></script> <script src="{{ MEDIA_URL }}js/jquery.dimensions.js" type="text/javascript"></script> <script src="{{ MEDIA_URL }}js/jquery.hoverIntent.js" type="text/javascript"></script> <script src="{{ MEDIA_URL }}js/jquery.cluetip.js" type="text/javascript"></script> {% else %} <script src="{{ MEDIA_URL }}js/jqbase-min.js" type="text/javascript"></script> {% endif %} In the settings file I maintain some variables for the JSC command. JSC_PATH = '/path_to_media/static/js' JSC_FILES = ( ('jqbase-min.js',('jquery-1.2.2b.js', 'jquery.cookie.js', 'jquery.dimensions.js', 'jquery.hoverIntent.js', 'jquery.cluetip.js')), ('jqui-min.js',('ui.mouse.js','ui.draggable.js', 'ui.draggable.ext.js', 'ui.droppable.js', 'ui.droppable.ext.js')) ) # either jsmin or jspacker, defaults to jsmin JSC_METHOD = 'jsmin' The first one is the path to the javascript files, the second is a list of compacted filenames and list of files to be included in the compacted one. The third setting is the method to compact the javascript, with options being the jsmin or the jspacker. Then in the command line I run ./management.py jsc to build the compacted files before deployment. …