Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Django patterns part 3: efficient generic relations
I've previously talked about how to make reverse lookups more efficient using a simple dictionary trick. Today I want to write about how this can be extended to generic relations. At its heart, a generic relationship is defined by two elements: a foreign key to the ContentType table, to determine the type of the related object, and an ID field, to identify the specific object to link to. Django uses these two elements to provide a content_object pseudo-field which, to the user, works similarly to a real ForeignKey field. And, again just like a ForeignKey, Django can helpfully provide a reverse relationship from the linked model back to the generic one, although you do need to explicitly define this using generic.GenericRelation to make Django aware of it. As usual, though, the real inefficiency arises when you are accessing reverse relationships for a whole lot of items - say, each item in a QuerySet. As with reverse foreign keys, Django will attempt to resolve this relationship individually for each item, resulting in a whole lot of queries. The solution is a little different, though, to take into account the added complexity of generic relations. Assuming the list of items is all … -
Stupid simple templatetags with Django
Writing simple templatetags is only marginally less painful that writing complex tags. django-simpletags aims at making writing simple tags simple. -
Our new website on App Engine
It's nonrel blog time, again! We really wanted to post last week, but we had to finish something before PyCon. Drums please... We've moved our blog to our new website built with Django nonrel. It's hosted on App Engine, but it should also work with other cloud DBs once we have more DB backends. The code is open-source, so you can build your own Django nonrel-based website and contribute improvements. The project comes with a simple CMS (a shamefully simple CMS :) and you can also create multiple independent blogs. For example, we now have two blogs on this site: Life & work: This will be some kind of life and work (practices) diary - without code Django nonrel / NoSQL: That's the blog you are reading now For now, we'll mostly focus on Django, but if you want to follow us more closely you should also consider subscribing to the other blogs. Features All content is written in reStructuredText markup and Pygments is used for code highlighting. You can manage all pages and blog posts via the admin interface. Comments are handled by Disqus. It doesn't make sense to write a new comments app because Disqus offers a much … -
Django tip: Automatic logins
In the Django documentation we see the following: When you’re manually logging a user in, you must call authenticate() before you call login(). That’s all really nice, because it makes sure that all your authentication backends are tried out; but if you want a really quick remedy for getting the job done, then you’ll need to set the user.backend property to the specific backend that authenticated the user. Beware that the Django developers can change these requirements. I wanted this to avoid writing my own backend, so I did this to log users in via a special view accepting a hash from the URL (from an e-mail that had a link that’d automatically log a user in). This could also become useful if you want to become a different user. def get_hash(s): import hashlib m = hashlib.md5() m.update(str(s) + settings.LOGIN_SECRET) return str(m.hexdigest()) def auto_login(request, user_id, secret): user = get_object_or_404(User, id=user_id) if not secret == get_hash(str(user_id)): raise Http404() user.backend = "django.contrib.auth.backends.ModelBackend" login(request, user) return HttpResponseRedirect(reverse('frontpage')) BEWARE! I strongly suggest that you don’t log any superusers in this way. You could add a conditional statement not user.is_superuser or similar. -
To hell with web standards
Ian Hickson (emphasis added): Someone whom I can’t identify publicly, since he posted only on one of the secret W3C member lists, contributed to the following thread […] Net result: the latest publication of HTML5 is now blocked by Adobe, via an objection that has still not been made public […] Secret W3C member lists? Anonymous holds? What is this, the Senate? Some might say this is Adobe’s fault. -
Why toppcloud will not be agnostic
Why toppcloud will not be agnostic. Ian Bicking’s toppcloud aims to offer deployment with the ease of use of AppEngine against a standard, open source Ubuntu + Python 2.6 + mod_wsgi + Varnish stack. Here he explains why he’s not going to vary the required components: keeping everything completely standardised means everyone gets the same bugs (and the same fixes). -
Python 2.6 - an orphan child
The current dominating version of python is 2.5. Most of the frameworks and vendors have comfortably settled on 2.5. Some of the upcoming technologies will support Python 3 exclusively. That leaves our old friend Python 2.6 out in the cold. The situation Python 2.6 - it is really not worth the effort to support it. I mean if you start breaking your code and such, you might as well upgrade to Python 3. The problem Python 2.6 provides a lot of nice features over Python 2.5 ("except as" is my personal favorite). A lost of the libraries are standardized (e.g. json over simplejson) and improved in terms of performance. However - it is not backward compatible to 2.5. The version difference of 0.1 makes it very easy to start using Python 2.6 for everything only to realize at the end that one has to regress to 2.5 for production. The solution Either stick with python 2.5 or stick with python 2.5. Conclusion It seems that in quest of progress, and by splitting their core language into three, Python community has went against one of it's core principles: "Simple is better than complex". After all if your application uses components all … -
Presenting django-devserver, a better runserver
Presenting django-devserver, a better runserver. I really like this—it’s a Django management command (./manage.py rundevserver) which adds SQL logging and cache access summaries to the console output of Django’s local development server. It solves a similar set of problems to the debug toolbar, but requires slightly less setup and doesn’t inject additional HTML in to your pages. You can add your own custom modules to it as well. -
Eating my own Dog Food
For several years now I've hosted this blog here on blogspot/blogger. Its been both a good and bad experience. For writing out simple posts it has made things pretty easy. However, if I try to post code examples I've got to deal with the various quirks of the blog engine. How it escapes special characters and that you can't easily do color colorization has been really annoying. Yes, I know you can do some hoop jumping to make this work, but I decided a long time ago that if I had to do that then I would host my own blog.Speaking of which, a few months back I got called out for not eating my own dog food. Yup, as a Python developer shouldn't I use something Python powered? I currently do Django professionally so those are in my tool chest so this should be trivial. Heck I also do some serious Pinax work so why not that?Whatever I put it under, it would be a nice move. I would be able to format and control my blog to a much better degree. I could easily supply code examples. I could use the hosting to demonstrate pet projects or launch … -
Picture Perfect
The hot new feature this week is photos. We've added the ability to attach your own photos of what you make to your recipes. This is a pretty early version, so we want to polish things more as we go, but please don't let that stop you from uploading pictures of your latest creation! Added photo galleries to recipes. For example: Whole Wheat Graham Bread Fixed the way ingredient/instruction sets are created. If you have a recipe that looks wrong to you, simply edit and re-save it and it should look much better afterward. Fixed an issue in the forking history where the path to the current recipe lacked highlighting. Fixed misleading text about who's recipe it was in the forking history. Fixed how the "Original Recipe" link works in forking history. Featured recipe of the week: Raw Fudge Balls by Madeleine McLaughlin. We tried these this past week and they were fantastic. My two boys adored them and more than once my wife caught them sneaking into the fridge for more! -
Deployment Using Capistrano / Webistrano via Rails / Phusion Passenger
I finally got around to setting up a more sophisticated deployment system for some of my apps. These apps include some built on a custom PHP framework and others that are Python / Django apps. I figured I'd share my experience... Why is a high-level deployment infrastructure important? Deployment is something that should be simple, [...] Related posts:Installing Ruby Enterprise Edition with Phusion Passenger Improved deploy:cleanup for capistrano 8 Books To Get A Developer For The Holidays -
Integrate Tornado in Django
Integrate Tornado in Django. A handy ./manage.py runtornado management command for firing up a Tornado server that serves your Django application. -
SubHub
За выходные дописать до рабочего состояния не вышло, устал очень... Идея состоит в том, чтобы сделать персональный PSHB-хаб, который можно использовать в Джанго-проекте в связке с блогом, форумом и вообще чем угодно, что генерит новые записи. Хочется попробовать повозиться с PSHB в реальности и заодно поймать кайф от мгновенного появления собственных записей в Гуглоридере (хотя я даже не знаю достоверно, поддерживает ли он PSHB :-) ). Проект окрестил "SubHub". Название SubHub намекает на то, что это хаб, который работает только с Subscriber'ами, но не с Publisher'ами: единственный его Publisher -- это ваш собственный сайт. Это упрощает дело примерно в половину, потому что не нужно реализовывать ту часть, которая отвечает за пинги от Publisher'ов. Уведомление SubHub'а о том, что что-то изменилось, происходит просто вызовом его функции в коде. Сегодня я успел написать: обработку запросов на подписку отложенную и прямую верификацию этих запросов вычищение протухших подписок И даже ещё ничего реально не тестировал. Осталось доделать: собственно рассылку нового контента подписчикам хранение того, что кому ещё не отослано подписывание контента HMAC-сигнатурой Если кто хочет поучаствовать, проект открыт на Launchpad'е. Для тех, кто ни одной DVCS кроме git'а не видел, вот небольшая вводная: Регистрируетесь на launchpad, закидываете туда свой публичный ключик. Учите локальную машину, … -
SubHub
За выходные дописать до рабочего состояния не вышло, устал очень... Идея состоит в том, чтобы сделать персональный PSHB-хаб, который можно использовать в Джанго-проекте в связке с блогом, форумом и вообще чем угодно, что генерит новые записи. Хочется попробовать повозиться с PSHB в реальности и заодно поймать кайф от мгновенного появления собственных записей в Гуглоридере (хотя я даже не знаю достоверно, поддерживает ли он PSHB :-) ). Проект окрестил "SubHub". Название SubHub намекает на то, что это хаб, который работает только с Subscriber'ами, но не с Publisher'ами: единственный его Publisher — это ваш собственный сайт. Это упрощает дело примерно в половину, потому что не нужно реализовывать ту часть, которая отвечает за пинги от Publisher'ов. Уведомление SubHub'а о том, что что-то изменилось, происходит просто вызовом его функции в коде. Сегодня я успел написать: обработку запросов на подписку отложенную и прямую верификацию этих запросов вычищение протухших подписок И даже ещё ничего реально не тестировал. Осталось доделать: собственно рассылку нового контента подписчикам хранение того, что кому ещё не отослано подписывание контента HMAC-сигнатурой Если кто хочет поучаствовать, проект открыт на Launchpad'е. Для тех, кто ни одной DVCS кроме git'а не видел, вот небольшая вводная: Регистрируетесь на launchpad, закидываете туда свой публичный ключик. Учите локальную машину, … -
Using class-based views effectively
Object-oriented programming stresses the idea of code reuse, through concepts like inheritance and polymorphism. View programming in django can sometimes get a boost from class-based design. -
Faster or lazier pagination
Or how to avoid slow counts in Postgres -
MongoEngine - MongoDB ORM for Python
MongoEngine is a Document-Object Mapper for working with MongoDB from Python. It uses a simple declarative API, similar to that of the Django ORM -
Naming Screen Sessions
I develop a number of Django-powered websites at work, and usually I want to leave them running when I’m not working on them so others can check out my progress and give me suggestions. The Django development server is incredibly useful when developing, but it’s not detached from the terminal so as soon as you [...] -
New Feature Tuesday!
The big new feature this week is the addition of "fork history". We've wanted a way to show the "family tree" of a recipe since we first started thinking about the site. This is available on every recipe. We have more improvements planned for it, but it's the start of what we want. Added fork history. Added search history. You'll find a list of recent searches in the sidebar. We also have recent/popular searches hooked up in the main search area and have trending stats at http://forkinit.com/stats/search/most_recent/ & http://forkinit.com/stats/search/most_popular/. The activity on your dashboard no longer shows duplicates if the same thing was done multiple times (like refreshing a recipe). It takes us a little bit to process recipes when they're created or forked. We're disabling those buttons on submission to prevent duplicates from being created. Fixed a bug where "followed" links in the activity areas would go to the wrong place. Fixed a bug where it appeared that you could have "-1 previous edits". Thanks for the report, Jeff! We also have two more features nearly complete, some major infrastructure work related to tags and some visual changes coming down the pipe. -
New DjangoSki speakers
Pleased to say that DjangoSki picked up a couple of good speakers. Andy Smith is a developer at Google, where he works on Google App Engine. He'll be speaking on Google App Engine and how to develop apps for it. Also he'll be talking about the status of non-relational backends for App Engine. A handy person to be sprinting with. Michael Richardson is one of the brains behind Urban Airship and Bac'n.com. He'll talk about django-piston and building an API in Django which Urban Airship use to do cool things for the iPhone. Also pleased to note that Rob Hudson is making his way up from Portland. Rob is the writer and maintainer of Django Debug Toolbar. Possibly the most useful debug tool you'll ever use in Django. As a connoisseur of fine Portland beer, I hope you'll be buying him a beer. -
Middleware post-processing in Django: a gotcha
One of the requirements for the new Heart website we've just launched was to allow users to personalise their location to one of 33 radio stations across the country. For various reasons, this meant rewriting all the links on the page, dynamically, depending on the user's location setting. The easiest place to do this sort of post-processing in Django is in response middleware. So I wrote a quick class that used regexes to grab all the href and action attributes (for a and form elements respectively - images didn't need localising) and add the relevant locations. Because it was dynamic, I used the ability of re.sub to call a function to determine the replacement value; and to save on multiple database queries, I saved various things in the instance. So it looked a bit like this: href = re.compile(r'(href|action)=["\'](.+?)["\']') class LocalisationMiddleware(object): def process_response(self, request, response): self.current_station = get_station(request) self.stations = Station.objects.values_list('slug', flat=True) content = href.sub(self.re_replace, response.content.decode('utf8')) response.content = unicode(content) return response def re_replace(self, matchobj): current_station = self.current_station url = "/%s%s" % (current_station.slug, matchobj.group(2)) return "%s=%s" % (matchobj.group(1), url) But then, during testing, we started getting some rather odd bug reports. Someone would be happily browsing the London pages, and would … -
Middleware post-processing in Django: a gotcha
One of the requirements for the new Heart website we've just launched was to allow users to personalise their location to one of 33 radio stations across the country. For various reasons, this meant rewriting all the links on the page, dynamically, depending on the user's location setting. The easiest place to do this sort of post-processing in Django is in response middleware. So I wrote a quick class that used regexes to grab all the href and action attributes (for a and form elements respectively - images didn't need localising) and add the relevant locations. Because it was dynamic, I used the ability of re.sub to call a function to determine the replacement value; and to save on multiple database queries, I saved various things in the instance. So it looked a bit like this: href = re.compile(r'(href|action)=["\'](.+?)["\']') class LocalisationMiddleware(object): def process_response(self, request, response): self.current_station = get_station(request) self.stations = Station.objects.values_list('slug', flat=True) content = href.sub(self.re_replace, response.content.decode('utf8')) response.content = unicode(content) return response def re_replace(self, matchobj): current_station = self.current_station url = "/%s%s" % (current_station.slug, matchobj.group(2)) return "%s=%s" % (matchobj.group(1), url) But then, during testing, we started getting some rather odd bug reports. Someone would be happily browsing the London pages, and would … -
Ressenya de creant Bits, el déjà vu
El segon creant bits dedicat a la introducció de Python i Django d'ahir va a tornar aplegar un bon nombre de gent interessada per la programació i per Python i Django. Cares conegudes i gent que vaig poder desvirtualitzar. Em va fer especial il·lusió poder desvirtualitzar Guillem, ja que per un motiu o altre mai ens havíem pogut trobar personalment. Aquesta vegegada preferírem no allargar molt la jornada i no es donà la xerrada damunt la posada en producció d'aplicacions Django. La passada jornada En Bernat va tenir molt poc temps i acabarem molt tard, així que ho hem deixat per a una millor ocasió. Aquest pic el consum de gominolas per part dels assistents va ser menor, lluny del rècord de kilo i busques de l'altra vegada. :-P La idea és que si algú s'avorreix al manco se n'endurà un sabor dolç de boca. Entre l'anecdotari comentar el mal cos que se'ns quedà a tots quan un tassó d'aigua va vessar damunt un portàtil Macbook Pro nou de trinca. Després de netejar-lo va tornar a la vida i esper que segueixi així. Hi va haver un segon intent de tragèdia, quan el que es va vessar va ser cafè … -
Django Meetup slides and little update
Due to a busy week, we can only provide a short update this time. Andy Smith from Google (and a Jaiku developer) has done a little presentation on Django on App Engine at the San Francisco Django Meetup on January 27th. Unfortunately, there is no video, but you can at least take a look at his slides. The talk was mostly about App Engine and the last third was about Django on App Engine. He also talked about the Django non-relational project, but nothing in depth and there were no demos. There were also a few other Google developers at the meetup, so hopefully we could get some more attention from Google and the Django community. We'd love to have some more impressions from people who attended the meetup. Were there any interesting questions? Another little update is that recently I added "startswith" query support to the App Engine backend. It's based on the unicode trick described in the App Engine documentation. This means you'll need a composite index for this kind of query if you combine it with other filters and you can't order by a field other than the "startswith" filter's field. Still, this should help with getting … -
Returning an actual proper real life HTTP code from a Django error page
Go to a non existent page on a Django site and you will (hopefully) be met with a friendly error page telling you not to panic, everything is OK and all you’ve done is mistyped the URL or something. If it’s your thing, you may be interested enough to look see what the actual HTTP code for the page is in the header; chances are that it will be a 200 rather than a 404 as the default handler just passes the dealings onto the HttpResponse class. Generally speaking this is fine, but there are situations where an accurate code would be very handy, as I found out the other day when I was trying to detect whether a file had been uploaded to a remote server. Scraping the resultant HTML for “Page not found” is not my idea of a robust solution. So, instead, pass the error page’s HTML into the respective class by putting something like this in urls.py: handler404 = 'urls.return_404' handler500 = 'urls.return_500' def return_404(request): return HttpResponseNotFound( render_to_string("errors/404.html")) def return_500(request): return HttpResponseServerError( render_to_string("errors/500.html")) Fullest of props to PiotrLegnica at Stack Overflow for this most elegant of solutions. Edit: After further examination (see the comments) the default …