Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
PyCon Rio: e lá vou eu...
Confirmado: estou indo para a PyConBrasil, edição Rio de Janeiro. O evento ocorrerá durante os dias 18, 19 e 20 de setembro. Estarei por lá nos dias 17 à 21. Quem vai? Será que galera da Django Brasil estará em peso por lá para um encontro informal!? Maiores informações, no site do evento: http://pyconbrasil.com.br/. -
StaticGenerator for Django Updated (1.3.3)
As reported by Matt Dennewitz, Django changed the request attribute path to path_info in rev 8015. StaticGenerator has been updated to reflect the change. -
Building a website API with Django. Part 4: Complex functions
We've talked about how the API functions are defined in WAPI, but we've only scratched the surface. This entry will go on details about function namespacing, optional parameters, parameter sets, parameter validation and allowed request methods, showing some real examples from the code I wrote for byNotes. Namespacing your functions As we've seen in the first post in this series, you API is loaded at an URL, for example http://example.com/api/1.0/rest/, so if you define a function named foo, it will be accessible from http://example.com/api/1.0/rest/foo.xml (or json or yaml). This is enough if your API consists only of a few functions. But what happens when your API has 50 functions? WAPI provides support for namespacing your API. You only need to prepend your method with your namespace name and the binding will take care of splitting them. For example, the ReST binding uses the pattern namespace/function_name, while the upcoming XML-RPC binding will use namespace.function_name. Let's see an example: class BynotesApi(object): ... @required_parameter('id', int, _('The geoname id you want to retrieve information for.')) def geo__hierarchy(self, request, dct): """Returns the hierarchy for the given geoname id, starting from itself.""" try: geoname = Geoname.objects.get(pk=dct['id']) except Geoname.DoesNotExist: return SingleSerializableResponse(None) return SerializableResponse([geoname] + geoname.hierarchy) As you … -
Celebrity Fantasy Game in Django
If you've played fantasy football or any fantasy sport you know what I'm takling about. If you're new to the concept, you pick a roster of celebrities and if they show up in the news, you get points. The site was written using Django (trunk as of the 13th!) and Postgres 8.2. We've built a fantasy games package on top of the Django core which we would probably open-source if the community showed some interest in it. This is our 2nd major site in Django and we really love it. To begin with, Python is a great language. When we built our fantasy engine, it was originally coded on MySQL. We encountered quite a few problems porting it over to Postgres. There are lots of little things where MySQL does type conversions for you automatically and Postgres (correctly in my opinion) does not. I definitely feel the conversion was worth it so that now we're on an enterprise level database. A side project that matured during this project is a multi-threaded mail delivery engine. It comes with some handy functions to send fully HTML/txt encoded emails with images embedded and all. I'll create a snippet for that mail engine in … -
Building a website API with Django. Part 3: OAuth in Django
I've received some emails asking for the WAPI code, so I'll start addressing that point. The code I'm including in this series doesn't work with the latest releases of WAPI and django-oauthsp, so you'll have to wait until I prepare the new releases. I'm just holding them until I finish writing this post series because, while writing about these APIs, I'm still adding new features, fixing some bugs and making the syntax nicer. I still have to write three more posts (complex functions, serializations and documentation), so you can expect a release around the end of this month. I'll write an entry announcing it. I had initially planned to include all the remaining information for API authentication in this post, but since I have to explain how you can integrate django-oauthsp into your projects, it turned to be so long. HTTP Basic authentication has been already covered, so the only missing bit regarding authentication would be HTTP Digest using the digest application. I'll explain it in one of the remaing posts in this series that turns to be shorter than expected. OAuth protocol implementation in django-oauthsp django-oauthsp implements the OAuth Core 1.0 protocol plus four extensions. Two of them are … -
Django: Inserting and Positioning Images
A few days ago I stumbled upon a thread over at the Django users mailing list discussing how to handle media in Django. It raised the interesting question of how do you associate images and files with your articles, blog posts, etc. When I started this blog I — too — realized I needed a way to insert and position images in my blog posts. Django only gives you a way to store text and images and leaves the rest up to us, the users of Django. My solution uses Markdown as the markup language. All my post are written and stored in the database as Markdown. Markdown might be too low-level for end users or non technical editors. It is more than user-friendly enough for me, but your milage may vary on this depending who’s creating the content on your site. One of the nice things about Markdown is that it has a very handy syntax for inserting images without having to type any HTML: 1 2![Alt text][id] [id]: url/to/image "Optional title attribute" Running the above through Markdown will convert it into a nice <img> tag. However, I would have to manually figure out and insert the path to all my images, … -
Cross-domain Session Cookie for Multiple Domain
Django provides for cross-domain session cookie settings. By default your session cookie is only set for your subdomain (example.com or blog.example.com). What django's cross-domain cookie settings does, however, is set it for all sub-domains. That is if your user enters your site from example.com, your session's cookie will be set as '.example.com' which in turn make it available to all sub-domains: foo.example.comHere is the docs for this settings:# Default: None # The domain to use for session cookies. Set this to a string# such as ".lawrence.com" for cross-domain cookies, or use None# for a standard domain cookie. See the session docs.SESSION_COOKIE_DOMAIN = '.lawrence.com'The problem with this settings comes in when you intend to have your django setup serve multiple domains. That is, this setting will explicitly set the cookie's domain as '.lawrence.com' which in turn prevents the any other domain to obtain a cookie pointing to this django setup.Out there to see how I can address this issue, I changed the behavior of this setting to also allow for automatic insertion of whatever host as such:SESSION_COOKIE_DOMAIN = '.%(host)s'the above settings works as well as the old behavior:SESSION_COOKIE_DOMAIN = '.lawrence.com'Click here to download the patch and replace it with your:/django/contrib/sessions/middleware.py -
Adding search to a Django site in a snap
Search is a feature that is – or at least, should be – present on most sites containing dynamic or large content. There are a few projects around to tackle that. Here’s a non-exhaustive list: djangosearch, django-search (with a dash), django-sphinx. Those search engines are great, but they seem like overkill if you just need a simple search feature for your CMS or blog. To deal with that, I’ve come up with a generic and simple trick. All you need is copy/paste the following snippet anywhere in your project: import re from django.db.models import Q def normalize_query(query_string, findterms=re.compile(r'"([^"]+)"|(\S+)').findall, normspace=re.compile(r'\s{2,}').sub): ''' Splits the query string in invidual keywords, getting rid of unecessary spaces and grouping quoted words together. Example: >>> normalize_query(' some random words "with quotes " and spaces') ['some', 'random', 'words', 'with quotes', 'and', 'spaces'] ''' return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)] def get_query(query_string, search_fields): ''' Returns a query, that is a combination of Q objects. That combination aims to search keywords within a model by testing the given search fields. ''' query = None # Query to search for every search term terms = normalize_query(query_string) for term in terms: or_query = None # Query to … -
Postback: Horror story with GeoDjango
Instead of replying to the comments, I decided to write a postback, since there are a few points I want to address. As John De Rosa guessed, I expecteded to receive some flamage because I've been in both sides situations like this before and I know it works. I've been the flamer and the flamed, but everytime the discussed issue ended up solved much anticipately that expected. We (people involved in FOSS) don't like flames, so when people start flaming, we look at the issue much quicker. That's how it works. Remember the Linus vs. Gnome flame? As D (BTW, it would be nice if people posted with their real names) pointed, I'm possibly using the wrong approach for the distance queries. But the truth is I didn't come with that ORM call myself. I got it from the GeoDjango documentation. So we have another problem here: the documentation has wrong examples. If you put something in the examples, don't yell when people tell you it doesn't work, And finally, as M pointed, I haven't got in touch with the GeoDjango developers. But that's because I have nothing useful to report. Shoud I report a bug telling: "Hey, I loaded … -
Horror story with GeoDjango
Last week I ported my geonames application to GeoDjango and I've ended up reverting all the changes and turning back to custom SQL. First, let me tell you what the geonames database is about. It contains almost 7 million geographical places and you can download the full dump under a Creative Commons BY-SA license. The first problem I encountered was importing the dataset. Since I need to do additional processing in their database dumps, I can't simply COPY the files to the database. When GeoDjango didn't exist, I decided to write a python script using the DB API and insert all the records that way. It worked fine, but it wasn't portable between different databases. So, when porting django-geonames to GeoDjango, I started by modifying the import script to use the Django ORM. First fail!. The script started running (with settings.DEBUG = False) and two hours later (importing the data with the Python script took around 1 hour) the OOM started killing processes. Well, I decided to left the script as it was before, but port the models and the custom SQL calls to the GeoDjango ORM. And I modified the models, adding some spatial fields and then removed all … -
Building a website API with Django. Part 2a: API authentication
As Gregor Müllegger suggested, I'm now writing about API authentication. This article talks only about user authentication methods without external dependencies, while methods which require other applications have been left for the next article. I was going to include them all in one article, but since I would also need to explain how django-digest and django-oauthsp work, this article would be too long. How authentication works in WAPI Authentication in WAPI works by using a middleware layer. WAPI ships with authentication middleware for HTTP Basic, HTTP Digest and OAuth. You'll usually need to subclass one of the provided middlewares, since the authentication realm is part of the class. When you plug a WAPI binding you can choose to add an authentication middleware class to it. Adding multiple authentication classes at the same API url is not supported, since different authentication methods return different WWW-Authenticate. However, you can support multiple authentication methods by using multiple API urls. For example, let's see my urls.py at byNotes: # urls.py from notes.api import BynotesApi, ApiAuthOAuth, ApiAuthBasic ... (r'^api/1.0/rest/oauth/%s$' % RestBinding.PATTERN, RestBinding(auth=ApiAuthOAuth(), api=BynotesApi())), (r'^api/1.0/rest/basic/%s$' % RestBinding.PATTERN, RestBinding(auth=ApiAuthBasic(), api=BynotesApi())), Requesting user authentication WAPI comes with a login_required decorator, which is not the same decorator provided by … -
Building a website API with Django. Part 1: API functions
WAPI and django-oauthsp are reaching the point when they are starting to become useful, so I decided it was time to write some articles explaining how they work and how you can use them in your sites. I'm currently using both of them in production at byNotes and I haven't run into any problems for now, but YMMV. This article talks about the principles behind WAPI and walks you trough the creation of a simple API function. Next articles in this series will explain more advanced concepts like custom serializations, user authentication against django.contrib.auth or using OAuth. Design Let's start by talking about the design ideas behind WAPI. My main motivation when I started writing it was abstracting most of the details involved in publishing a web API, since almost 100% of sites have the same requirements: ReSTful resources (sometimes SOAP or XML-RPC), serialization in different formats and user authentication. Handling all of this as views is not difficult, but it's tedious and a lot of times requires more code than the API itself. So, why not let the developer focus on providing useful endpoints and let a framework do the rest? WAPI only requires you to write a class. … -
MultipleSubmitButton Widget for ChoiceField
Recently I published a snippet with a widget rendering a choice field as a series of submit buttons.So the {{ form.do }} field from the following form:SUBMIT_CHOICES = ( ('save', _("Save")), ('save-add', _("Save and Add Another")), )class TestForm(forms.Form): do = forms.ChoiceField( widget=MultipleSubmitButton, choices=SUBMIT_CHOICES, )will be rendered as:<ul><li><button type="submit" name="do" value="save">Save</button></li><li><button type="submit" name="do" value="save-add">Save and Add Another</button></li></ul>Can somebody enhance this widget so that it supports iteration through different choices and getting specific buttons by indexes in the template? My trials failed, but maybe you will succeed! -
Proxying Django's admin views
In this post I share some thoughts on one way to customise the Django’s admin interface beyond what, I believe, it was originally designed for. Well, at least it’s an approach that I used to bring django-treemenus’ codebase up to the NewForms-Admin’s API, while preserving the app’s original behaviour. First, you may want to check the latest release of django-treemenus (0.6). In that release I’ve completely refactored the code to use all the goodness of NFA. Backward incompatible changes are minimal if you weren’t using the extension system, and from the user’s point of view everything is pretty much the same as before. The result is quite satisfactory: the amount of code was reduced by more than half, every known issue was fixed, and it is now much easier to extend/hack this app for those who are interested. Doing that refactoring made me realise even more how great NFA is. Still, I did not quite want to use it the “standard” way. Basically, I wanted to keep the URL scheme that was used in previous versions of treemenus. For example: /admin/treemenus/menu/1/ -> The menu #1 edit page. /admin/treemenus/menu/1/items/add/ -> Add an item to menu #1. /admin/treemenus/menu/1/items/9/ -> The item #9 … -
"Cool project, what CMS did you guys use?"
Pass223.com I recently worked on Pass223.com, a simple site that urges the Senate to pass a piece of legislation that requires the Senate to adhere to the same electronic financial disclosure rules in place for representatives and presidential candidates. Pass223.com is similar to that of hundreds of related action sites: choose a legislator, call them, report results, repeat. I wrote the code, our esteemed creative director Kerry did the bulk of the design, and various others here at Sunlight helped to refine the concept and wording of the site and call script. It was a bit surprising seeing how positive the feedback has been for such a simple site. A number of people have been pointing to Pass223 as an example of how this type of thing should be done. Most of that credit goes to the team that worked together to revise the awesomely straightforward script. The other question that has come up is what content management system (CMS) Pass223 was done on and what legislative database it was built on top of. This made me think about the other reason Pass223 was able to come together the way that it did, the tools used behind the scene. When … -
Kansas Primary 2008 recap
I’m winding down after a couple of very long days preparing for our coverage of the 2008 Kansas (and local) primaries. As always it’s been an exhausting but rewarding time. We’ve come a long way since the first election I wrote software for and was involved with back in 2006 (where election night involved someone accessing an AS/400 terminal and shouting numbers at me for entry). Our election app has become a lot more sophisticated, our data import process more refined, and election night is a whole lot more fun and loads less stressful than it used to be. I thought I’d go over some of the highlights while they’re still fresh in my mind. Our election app is definitely a success story for both the benefits of structured data and incremental development. Each time the app gets a little more sophisticated and a little smarter. What once wasn’t used until the night of the election has become a key part of our election coverage both before and after the event. For example, this year we had an overarching election section and also sections for indivudual races, like this section for the Douglas County Commission 2nd district Democratic primary. These … -
Eclipse 3.4 Ganymede and PDT
Unfortunately there is no working and official version of the PDT release for the current Eclipse release, Eclipse 3.4 Ganymede. However it is possible to use both. I found the solution within the Digital Base blog: Simply download the nightly build of PDT and integrate it as local site in the Eclipse update manager and then install. Quite easy. -
Eclipse 3.4 Ganymede and PDT
Unfortunately there is no working and official version of the PDT release for the current Eclipse release, Eclipse 3.4 Ganymede. However it is possible to use both. I found the solution within the Digital Base blog: Simply download the nightly build of PDT and integrate it as local site in the Eclipse update manager and then install. Quite easy. -
Eclipse 3.4 Ganymede and PDT
Unfortunately there is no working and official version of the PDT release for the current Eclipse release, Eclipse 3.4 Ganymede. However it is possible to use both. I found the solution within the Digital Base blog: Simply download the nightly build of PDT and integrate it as local site in the Eclipse update manager and then install. Quite easy. -
Django: messaging
When completing something like deleting an item or adding a user, it’s usually nice to report a message to the user to let them know what just happened. I also find it useful to send the user somewhere they’d “want” to go. For example, if they just created a user, send them to the list of users page, so they see the change they just made. I’m also a big advocate of keeping URLs clean. Because of these concerns the best answer in Django is to do an HttpResponseRedirect. Now the problem with that is that you can’t pass data to a redirect. To get around this there are messages that you can send to the users session itself. The mechanism isn’t that clean, but it does work, and it does do the job. So if you have a logged in user all you need to do to add messages is: request.user.message_set.create(message='User successfully created.') Now the flip side to the equation is that you “get” the message(s). So how this works is when you set a message you’re actually adding a message to a list. When you”get” the message, you’re actually getting the list (may be more than one message). … -
Adding Your Twitter Status to a Django Site
As part of changing the layout of my blog I wanted to add my latest Twitter status to the bottom left corner. It turned out to be very straight forward. Python has an excellent Twitter API — very litle code was required. There’s two ways you could go about doing this. The first way is to write a template tag that would fetch the latest tweet, the other to create a context processor that would provide a tweet variable to your templates. I choose the latter. Before we can start, the Twitter API module needs to be installed. You can find both the module and installation instruction over on google code: http://code.google.com/p/python-twitter/. Note: I had to install the SVN version as there’s a bug in python-twitter version 0.5 when using Apache — it works fine using the development server. To set up a context processor we first need to specify where Django can find our processors. This is done using the TEMPLATE_CONTEXT_PROCESSORS setting. Add the below to your project’s settings.py file. 1 2 3 4 5 6 7 8from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS TEMPLATE_CONTEXT_PROCESSORS = TEMPLATE_CONTEXT_PROCESSORS + ( "mysite.blog.context_processors.latest_tweet", ) TWITTER_USER = "omh" TWITTER_TIMEOUT = 3600 Django has bunch of context processors already defined … -
New Django Paginator Example
edit: This example has since been added to the official Django Docs for pagination. Big thanks to Scot Hacker for taking the initiative to submit the doc patch and make this happen (IE I’m far to lazy to submit it on my own). So I pulled the latest Django codebase from svn today and I [...] -
Już jutro wersja Django 1.0 beta 1
Już jutro ma wyjść pierwsza wersja beta Django. Ostatnią bardzo ważną zmianą, było dodanie newforms-admin do drzewa głównego. Jednakże zmian jest coraz więcej. Choć nie tak dużych to równie ważnych i kłopotliwych. Lista tych rzeczy, które mnie najbardziej dotknęły. Zmiana zasady... -
Tema do Django para GNOME
Eu utilizo no meu GNOME o tema Clearlooks acho que desde que ele foi lançado. Tentei utilizar outros, mas nunca me acostumei. Depois que o grande pixel-artista Jader Rubini, fez um lindo fundo de tela para a comunidade Django Brasil, eu dei uma uma pequena personalizada no Clearlooks e o chamei de Django. E por que não? Tem as mesmas cores comumente utilizadas pelo Projeto Django. Eu achei que o conjunto (fundo de tela, clearlooks e cores) ficou bonito e agradável. Dê uma olhada: Minha área de trabalho. Se gostou também, você pode obtê-los nos links abaixo: Tema: django-gnome-theme.tar.gz Fundo de tela: DjangoBrasil_Wallpapers_by_jaderubini.zip -
DjangoCon!
I’m a little late to the announcement party, but I’ll be attending DjangoCon and sitting on a panel about Django in Journalism with Maura Chace and Matt Waite. The panel will be moderated by our own Adrian Holovaty. I think the panel will be pretty fantastic but I can’t help be just as terrified as my fellow panelists. I love that we’ll have both Journalist-programmers and Programmer-journalists on the panel, and I love that Django is so often the glue that brings the two together. DjangoCon is going to be awesome.