Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Growing open source seeds - Kenneth Reitz
He shows us three kinds of (more or less) open source projects. Type 1: public source Once upon a time there was an "open source project" called the facebook SDK. Basically it just stopped working one day and nobody could help, despite offers for help on the issue tracker. Hacker news got wind of it and it was on the front page for a while. Facebook's reaction? Disabling the issue tracker... (Later on they fixed it). That's not open source, that's public source. Often it is abandoned due to loack of interest, change of focus or so. The motivation for having it as open source simply is not clear. Type 2: shared investment A different example: gittip. They aim to be the world's first open company. There's a github issue for everything, even the company name. Major decisions are voted for on github. The code is open source, of course. All interviews with journalists are filmed and live-streamed. And all otherwise-often-backdoor-cooperation-agreements are fully open. Projects like gittip are shared investment projects. Shared ownership, extreme transparency. There is very little questioning of motivations. The motivation is clear and public. There's a documented process for new contributers. The advantage? It is low … -
Mock your database - Marc Tamlyn
Your database is slow. Especially for testing. Nobody likes waiting, so SPEED is essential. Speed of iteration. Faster unit tests mean more tests. No one likes waiting. Once you create a couple of model objects in your tests, you're going to hit your database. He did a quick test with some 8 database queries. 5 seconds for 1000 runs on postgresql. 4 seconds for in-memory sqlite, so that's a bit better. Why not use factory_boy? That could help, right? More efficient instantiation, perhaps, all in one go (as the test was with a bunch of related objects)? 6 seconds on postgres, sigh. Higher. He tried a dirty dirty dirty crazy hack, using Django internals. (I looked to my right and the #1 Django database core committer was grinning from ear to ear...). No database queries. 1 second. Better: mocking. So he did some still-quite-hacky mocking with the mock library. 1.2 seconds. Ok, but the code is a bit yucky. Summary till now: avoiding the database is quicker. The difference is bigger than the difference between postgresql and in-memory sqlite. So... write your code in such a way to make avoiding the database easier. But... is there a better way? He … -
Taming ajax and django - Marc Egli and Jérémie Blaser
Jérémie is a frontend developer and Marc does the backend. Address/state handling and content rendering are the two main challenges. Address and state handling Problems: Browser history. If you don't watch out, the back button won't be working. Deeplinking should stay possible. Crawler visibility: you want them to grab your entire site. But they don't use javascript. So you need a special URL for them Some solutions: A hash like http://yoursite.com/#/some/id. Javascript will need to handle everything behind the hash. Problem: without javascript it isn't visible. You're invisible to crawlers. It is easy to implement, though. A hashbang like http://yoursite.com/#!/some/id. The difference? Google and others replace the URL with http://yoursite.com/?_escaped_fragment_/some/id. You'll have to configure your website to support it. Deeplinks work this way and crawlers can access the site via links in a search engine sitemap. It works with almost all browsers. And it covers all three mentioned problems. You have multiple URLs, however. And you'll need to maintain legacy URLs. In django you could implement it with some middleware that detects the _escaped_frament_ GET parameter. Pushstate. The URL is a regular URL like http://yoursite.com/some/id. The best example is the github website. Pro: easier to implement on the backend, good … -
Know Your Models
In web development, we have a unfortunate double meaning for the word “models” and as obvious as the separation of those two seems to seasoned developers, it shows again and again that it’s not as obvious to beginners. Anyone who took a class on object-oriented design in the last 20 years has inevitable heard about MVC. While there are recurring (and consistently fruitless) discussions about what exactly is what, what should be named how and how they should interact, the basic common understanding is more or less: You separate your application into models, views and controllers (or models, templates and views). And ideally, you should be able to tamper with/replace either mostly independently of the other two. This article concentrates on the models part which is the data the other components work with and display to the user. Ideally it should be a pleasant API that abstracts away the storage intricacies. However… There is more than one kind of models… Django calls its ORM classes ‘models’. Pylons/Pyramid calls the skeleton part for SQLAlchemy ‘models’. I’m going to claim that that’s rather misleading since unless you’re building a simplistic CRUD application, your application models are not the same as ORM models … -
2013 EU Djangocon introduction
I'm at the 2013 European djangocon in Warsaw! Ready for three days of conferencing and, for me also, live blogging :-) Russell Keith Magee started off the conference. He remembered Malcolm Tredinnick, mentioning his code contributions, but especially his community involvement. Lots of mailinglist messages. Lots of personal involvement, too, as he visited many people and local communities. Not only Django: also chess, for instance. And he build a community here, too: working on the Australian chess community. He passed away unexpectedly a few months ago. Make the most of the time you have. It can be over quickly. And especially: be part of communities. Make communities work. And especially make this Django community work. Make friends. Enjoy our friendly community! -
Two scoops of Django book review
I took the train from Utrecht (NL) to Warsaw today. I only had to change in Amersfoort (NL) and Berlin (DE), so it was a pretty direct connection. 12 hours of train time (which I enjoy). So that's enough time to read through two scoops of Django, the Django book by Daniel Greenfeld and Audrey Roy! Here's my review. The summary: buy the book and learn a lot. For the longer version, I'll simply go though my notes I made for each chapter. Coding style The book starts off good, in my opinion, because it tells you to write good and neat code. PEP8. Good not-too-short variable names. And it got me thinking by advocating explicit relative imports ("from .models import SomeModel"). That's what's good about this book: Daniel and Audrey state preferences and tell you best practices and sometimes those best practices won't be your best practices. Or you didn't know something. Anyway, it gets you thinking; which is good and enjoyable. Virtualenv Hey, virtualenv in chapter two! Nice. Here, like in the rest of the book, I noticed they point a lot at existing documentation and don't provide much explanation. No virtualenv explanation here, for instance, just a … -
Circus: process and socket manager - Tarek Ziadé
Tarek Ziadé can't believe he's giving a talk about his circus process manager in an actual circus tent :-) A typical deployment is with nginx and gunicorn or uwsgi. But you add more and more items right next to your django process(es). Celery or haystack for instance. So you add a supervisor that starts 'em all. An often-used one is supervisord. You could use a system-level tool like upstart, but you need root access for that. You don't need it for supervisord. Supervisord has some missing features like a powerful web console, clustering, realtime output, remote access and so. Supervisord has some of this, but not good enough. So they (mozilla) started with Circus. They used several existing libraries, like psutil, zeroMQ, socket.io. psutil is the core of the system. Very handy for interacting with processes. It was a bit slow, but together with the psutils author they managed to make it fast. ZeroMQ is an async library for message passing, so more or less a smart socket. They use message passing for making the various process data available to the circus tools, like 'circus-top' or 'circusd-stats'. And because everyting is nicely decoupled, it is possible to add your own … -
The imaginative programmer - Zed Shaw
His goal: teach programmers to be more creative. He's got a love/hate relationship with creativity. The first part of his talk was impossible to summarize. You'll have to watch the video later on :-) Artists tell him he's not artistic because he works on developing technical skills. Guitarists tell him he's not a real guitarist as he doesn't play in a band. And 'cause he builds his own guitars he's a programmer, not a Real Guitarist. Writers tell him he's not a writer because he writes technical books. Programmers tell him he's not a programmer because he doesn't work on their project. And by the way, he's a (technical) writer now, so he's not a programmer. He's not creative enough. Or so the others say. Or he's not acceptable. How to deal with creativity? In a way, you can re-phrase creativity. Programmers are always making something from nothing, right? Isn't that the pinnacle of creativity? Here are four hypothetical persons: Technique, no imagination: a stereotypical programmer. Imagination, no technique: stereotypical biz dude. No imagination, no technique. Probably doesn't exist. Both imagination and technique. Zed's goal. Zed's imaginative programmer process. Everyone has a process (if they're good), here's the one he … -
Processing payments for the paranoid - Andy McKay
Everyone should be paranoid when processing payments. The client, the programmer, everyone. He works on Firefox OS and more especially the marketplace ("don't call it an app store"). The marketplace is powered by Django. And of course it accepts payments. And of course it is open source (even the presentation is on github). Btw, they have a bug bounty in place. If you find a real bug, mail them and they'll pay you a bounty! The firefox add-on website already allows donations for firefox add-ons, handled through paypal. 500-2000 dollar per day. But the marketplace will process much larger amounts of money, so they needed to increase their paranoia level. For online payments, you need tokens and credentials. And they need to be stored somewhere. And suddenly you're a big fat juicy target just waiting to be hacked. XSS (cross site scripting) is an oft-occurring problem. Django has build-in protection for common cases. There's also content security policy that further limits it. They also started navigator.mozpay. Phishing. In-person tricks. For instance for getting your hand on a database for test usage. You do need something for debugging, so they now create an automatic anonymized debug database. SQL injection and so. … -
Advanced PostgreSQL in Django - Christophe Pettus
(See also last year's talk) Database agnosticism: write once, run on any database. A critical selling point for Django: it runs on many databases. But for others, it is bad. You pay a performance hit for not using database-specific features. So once you have made your choice, really use that database. Here are some examples of good special things available in postgres. Custom types Custom types. If you like types, you'll love postgress. Many built-in types. And many are usable in Django by installing some small app. Do you do .lower() in python code or in your SQL? For an email address for instance? Why not use citext, a case insensitive text field provided by postgres. Often you want to add various key/value data to an object. Attributes. Extra table with a join? Add fields to the main table? Solution: hstore. Postgres has a built-in json type! No need for mongodb :-) It is validated going in. Postgres 9.3 will make it much faster. The UUID type is much more efficient than storing a long character string. IPv4 and IPv6 addresses. You can define your own! And it is easy to integrate into Python and Django: You adapt it into … -
Having your pony and committing it too - Jacob Burch
Jacob Burch hopes you can learn from him if you're new at contributing to open source. He won't cover virtualenv, git, django's core code structure. And also not what to get involved in. What's this talk about? About you if you have something you want ("a pony") to get into Django core. You are initially probably going to be a bit afraid. Jacob showed a couple of quotes about people that were initially not quite sure/certain when committing to Django. Then he showed the names of the people those quotes came from: they're now all core committers :-) Two balances you have to keep in mind: You should be both pro-active and patient. This is a tough balance to strike. If you manage it, it helps a lot. You should be both confident and humble. Be humble, but be convinced of your idea. How to help here? The best thing is to run all the tests. It will give you confidence that your solution works (if it does). And it'll make you humble once you realize all the end cases that Django (and thus your fix) needs to support. There are three broad categories of contributions: Bug fixes Start with … -
Getting recommendations out of nothing - Ania Warzecha
Ania Warzecha researched recommendation systems. Recommendations means estimating ratings or preferences for items a user hasn't seen yet. For example books or movies you might also like based on earlier purchases. There are three kinds of recommendations. Collaborative recommendations. Mostly created based on actions from other users. Which books are often bought together, for instance. Simple to implement, but can be slow for big datasets. And doesn't work well on new items and/or new users Content-based recommendations. Looks for similar items. Fast and accurate, but tends towards over-specifications regarding needed data. Hybrid methods. Combining them. A case study: a Polish car parts website. You normally don't log in there, you just want a part. So older purchases aren't available. They did have a lot of parts and data, so they started with content-based recommendations. They mixed in some basic user actions. 0=didn't buy, 1=browsed, 2=bought. Later on more elaborate, like points for items found through searching or items placed on wishlists. They used Redis for its quick addition of user actions, simply pushing an additional score to an item which then gets added in the database. One thing they needed to do was to merge session keys after a user … -
Thread profiling in Python - Amjith Ramanujam
Amjith Ramanujam recently wrote a thread profiler in Python and it was rediculously simple. He works for New Relic, which is all about performance and expecially performance measuring. Python comes with batteries included, so it also includes a C profiler that works pretty well. But it doesn't work nice for django because the output is so huge. If you use the GUI RunSnakeRun, it is more managable that way. Additional problem with cProfile: it has about 100% overhead, so you can't run it in production (which they need). You can do more targeted profiling. For instance in Django. The way a web framework processes requests is normally always in the same way. You can use that during profiling. There are two important stages: interrupt and inquire. Interrupt A statistical profiler looks how often a function is called and by who. For this it needs to interrupt the regular process. You could set an OS-level signal to call your profiler every x miliseconds so that it can do something. It only works in linux, btw. Another way is to create a python background thread that wakes up every x miliseconds. It is cross-platform and mod_wsgi compatible. It is less accurate for … -
Combining Javascript and Django in a smart way - Przemek Lewandowski
Django is a javascript-agnostic web framework. Nothing is built-in so you can be up to date all the time. Javascript development moves very quickly. The basic approach is to include some custom inline javascript in the html pages. It quickly leads to illegible code that's hard to work on and hard to distribute. Javascript has frameworks, too. They give your application structure and take work off your hands. This is the advanced approach. It includes several parts: Communication with the server (REST api, websockets). Application building: combining and minimizing files. Static files management. Javascript improvements: coffeescript and so. What Przemek Lewandowski needed was a powerful javascript framework, coffeescript, testable code, js code minimization and fingerprinting for avoiding caches. And also rapid REST API development. Javascript framework They started with backbone, but it wasn't enough. They added marionette to backbone, but it still wasn't good enough. There's a lack of a binding mechanism; there are no reusable views; models are poor. AngularJS and Ember are better. Coffeescript It is controversial, but it helps to write code faster and use less code for it. It performs as well as javascript as it compiles to javascript. They used requireJS for painless coffeescript integration. … -
Migrating the future - Andrew Godwin
Andrew Godwin attempted to raise 2500 pounds for inclusion of south in Django core with kickstarter. It worked. In fact, he raised 17952 pounds! Why does South need to be replaced by a new version inside Django itself? It started 5 years ago, so there's 5 years of learning done in that period. Some things that made sense at the time aren't the best decision now. There's poor support for VCS branching. The migration files are huge. Migration sets get too large. There are projects with 1000 steps! The inside-django solution has two parts. The actual migration code and a separate backend. So if you want a different migration engine, you can probably reuse the backend code with its support for multiple types of databases. The new migration format is more declarative instead of imperative like it is now. This makes them smaller. It also allows you to compute the end result in memory and apply one single migration. Migrations will have a parent. So you won't have a problem with 0003_aaaa and 0003_bbbb migrations that halfway bite eachother. If a merge can be done automatically, fine, otherwise south/django will warn you. Squashing will be added. You can squash a … -
Djangocon lightning talks day 1
Sorry if I mangled any of the names, I took a photo of the lightning talk submission form and tried to decypher them :-) From carrots to Django - Kamila Stephiouska She tells about the Geek Girls Carrots community. A community for women interested in new technology. 11 cities, 4 special meetings, 1 sprint, 5 kinds of workshops. They like to promote women working in IT. The held a "django carrot" recently: 14 hours, 10 mentors, 23 participants. They try to get special guests. Last week Daniel and Audrey came (the writers of two scoops of Django). See http://django.carrots.pl They chose Django because of the community. Don't be afraid to commit - Daniele Procida Lots of people work with Django. Lots of people program with it. There are barriers to getting them to work on Django. They might not be effective. They might be afraid. They might not communicate effectively. You also need to manage your code and your environment. Virtualenv fixes the environment, but you need to learn that first. Version control helps with your code, but you first need to learn version control. Similarly, you need to learn documentation and tests. And you need to learn to have … -
Copernicus, the great refactorer - Brandon Rhodes
Brandon Rhodes mentions Nicolai Kopernik, a famous Polish scientist. He "lifted Earth into Heaven" by his book where he put the sun in the center of our universe instead of Earth. We're no longer at the bottom. The near-earth environment was pretty well mapped out. 300BC, the size of the spherical earth was already known. Around 100BC the distance to the moon was known. But what about those planets? They were harder. Stars did move around the sky more or less linearly. But those planets. They seemed to move back and forth a bit. Did they need to have a different model? The sun-centric model was already known, but it didn't catch on. The reason? Medieval science was too emperic: the earth cannot be moving, it seems to stay in place. Throw a ball and it falls down again towards the earth, it doesn't career off into space. The church wasn't totally idiotic by later convicting Galileo: there was just no solid emperical evidence :-) One of the pieces of evidence that was missing was that there was no observable stellar parralax; visible movement between stars because of earth movement. It was only in 1838 that the instruments were good … -
Query a Random Row With Django
Here's a gist for a drop-in Django manager class that allows you to return a random row. Model.objects.random() It can be used in your models.py like this: class QuoteManager(RandomManager): def random_filter(self): return self.filter(is_active=True) class Quote(models.Model): quote = models.TextField() by = models.CharField(max_length=75) is_active = models.BooleanField(default=True) objects = QuoteManager() def __unicode__(self): return self.by Advantages over using the order_by('?') is performance. Random sort at the database seems to be extremely slow on most databases even if the table only has a few thousand rows. Note that the count of records is cached for 5 minutes, so if the table changes often you may want to change that. A limitation is that it only returns one row. -
Installing Django on Ubuntu memo
Here are a few notes and links after moving to the new Ubuntu server on linode.com. Some steps for security: My First 5 Minutes On A Server Install packages: 1 2 3 4 apt-get install apache2 libapache2-mod-wsgi apt-get install postgresql postgresql-server-dev-9.1 python-dev apt-get install mysql-server mysql-common mysql-client libmysqlclient-dev apt-get install git git-core Setup virtualenv: 1 2 3 4 apt-get install python-setuptools apt-get install python-pip pip install virtualenv virtualenv --no-site-packages /path/to/venv Install PIL in virtualenv: 1 2 3 4 5 apt-get install libjpeg libjpeg-dev libfreetype6 libfreetype6-dev zlib1g-dev ln -s /usr/lib/`uname -i`-linux-gnu/libfreetype.so /usr/lib/ ln -s /usr/lib/`uname -i`-linux-gnu/libjpeg.so /usr/lib/ ln -s /usr/lib/`uname -i`-linux-gnu/libz.so /usr/lib/ pip install PIL Enable apache mods: 1 2 a2enmod rewrite a2enmod expires Configs for Django apps: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 /path/to/site/app/wsgy.py import os import sys sys.path.append('/path/to/env/lib/python2.7/site-packages') sys.path.append(os.path.join(os.path.dirname(__file__), '..')) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings") import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() /etc/apache2/sites-available/site.conf <VirtualHost *:80> ServerName site.com ServerAlias www.site.com ServerAdmin admin@site.com DocumentRoot /path/to/site/ WSGIDaemonProcess site.com processes=2 … -
I've joined Heroku
I’ve joined Heroku as their Director of Security. Why? I started as a Heroku skeptic. The first iterations of Platform-as-a-Service left me deeply underwhelmed. “Deploying web apps is hard,” I said, “there’s no way you can just abstract it away like that.” I was wrong. Over the last few years I’ve gone from being a Heroku skeptic, to a user, to a fan, and now — an employee. Perhaps at some later point I’ll write a bit about how my thoughts evolved, but for now I’ll leave it at this: Heroku’s vision of a world where developers are empowered to deliver apps is one I support. -
One to Many
As of yesterday, I completed and merged the first of the three upcoming Evennia features I mentioned in my Churning Behind the Scenes blog post: the "Multiple Characters per Player" feature.Evennia makes a strict division between Player (this is an object storing login-info and represents the person connecting to the game) and their Character (their representation in-game; Characters are just Objects with some nice defaults). When you log into the game with a client, a Session tracks that particular connection.Previously the Player class would normally only handle one Session at a time. This made for an easy implementation and this behavior is quite familiar to users of many other mud code bases. There was an option to allow more than one Session, but each were then treated equally: all Sessions would see the same returns and the same in-game entities were controlled by all (and giving the quit command from one would kick all out).What changed now is that the Player class will manage each Session separately, without interfering with other Sessions connected to the same Player. Each Session can be connected, through the Player, to an individual Character. So multiple Characters could in principle be controlled simultaneously by the … -
Enabling CORS in Angular JS
I was recently experimenting with building an API with django-tastypie and make it accessible via CORS, so it can be used from a different host from an AngularJS app. For the Django part it was relatively straightforward. I could have either written my own Middleware, dealing with incoming CORS requests, but decided to use django-cors-headers in the end. Following the instructions in the github repo and adding my host where AngularJS is hosted to the CORS_ORIGIN_WHITELIST setting did enable the Django server to handle CORS. With AngularJS it was a little more tricky, mainly because information is spread all over the web. Beside the fact that I was trying to implement a service using ngResource to communicate with the API, the following did enable AngularJS to send its requests with the appropriate CORS headers globally for the whole app: var myApp = angular.module('myApp', [ 'myAppApiService']); myApp.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; } ]); _ Just setting useXDomain to true is not enough. AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. Removing the header is necessary, so the server is not rejecting the incoming request. -
Django Facebook – 1.5 and custom user model support
Django Facebook now officially supports Django 1.5 and custom user models! Go try it out and upgrade to pip version 5.1.1. It’s backwards compatible and you can choose if you want to keep on using profiles, or migrate to the new custom user model. Installation instructions can be found on github. Contributing Thanks for all the contributions! My startup (Fashiolista) depends on a reliable Facebook integration and maintaining it would not be possible without all the pull requests from the community. Contributions are strongly appreciated. Seriously, give Github a try, fork and get started :) About Django Facebook Django Facebook enables your users to easily register using the Facebook API. It converts the Facebook user data and creates regular User and Profile objects. This makes it easy to integrate with your existing Django application. I’ve built it for my startup Fashiolista.com and it’s currently used in production with thousands of signups per day. For a demo of the signup flow have a look at Fashiolista’s landing page (fashiolista.com) After registration Django Facebook gives you access to user’s graph. Allowing for applications such as: Open graph/ Timeline functionality Seamless personalization Inviting friends Finding friends Posting to a users profile Django Facebook … -
The Easy Form Views Pattern Controversy
This isn't a controversy 'per se', except perhaps in the feverish depths of my brain. In the summer of 2010 Frank Wiles of Revsys exposed me to what I later called the "Easy Form Views" pattern when creating Django form function views. I used this technique in a variety of places, including Django Packages and the documentation for django-uni-form (which is rebooted as django-crispy-forms). At DjangoCon 2011 Miguel Araujo and I opened our Advanced Django Forms Usage talk at DjangoCon 2011 with this technique. It’s a pattern that reduces the complexity of using forms in Django function-based views by flattening the form handling code. How the Easy Form Views pattern works Normally, function-based views in Django that handle form processing look something like this: def my_view(request, template_name="my_app/my_form.html"): if request.method == 'POST': form = MyForm(request.POST) if form.is_valid(): do_x() # custom logic here return redirect('home') else: form = MyForm() return render(request, template_name, {'form': form}) In contrast, the Easy Form Views pattern works like this: def my_view(request, template_name="my_app/my_form.html"): form = MyForm(request.POST or None) if form.is_valid(): do_x() # custom logic here return redirect('home') return render(request, template_name, {'form': form}) The way this works is that the django.http.HttpRequest object has a POST attribute that defaults to … -
The Easy Form Views Pattern Controversy
In the summer of 2010 Frank Wiles of Revsys exposed me to what I later called the "Easy Form Views" pattern when creating Django form function views. I used this technique in a variety of places, including Django Packages and the documentation for django-uni-form (which is rebooted as django-crispy-forms). At DjangoCon 2011 Miguel Araujo and I opened our Advanced Django Forms Usage talk at DjangoCon 2011 with this technique. It’s a pattern that reduces the complexity of using forms in Django function-based views by flattening the form handling code. How the Easy Form Views pattern works Normally, function-based views in Django that handle form processing look something like this: def my_view(request, template_name="my_app/my_form.html"): if request.method == 'POST': form = MyForm(request.POST) if form.is_valid(): do_x() # custom logic here return redirect('home') else: form = MyForm() return render(request, template_name, {'form': form}) In contrast, the Easy Form Views pattern works like this: def my_view(request, template_name="my_app/my_form.html"): form = MyForm(request.POST or None) if form.is_valid(): do_x() # custom logic here return redirect('home') return render(request, template_name, {'form': form}) The way this works is that the django.http.HttpRequest object has a POST attribute that defaults to an empty dictionary-like object, even if the request’s method is equal to "GET". Since we …