Category Archives: django

Ember Server Side Form validation with Django

In previous post (Ember Server Side Form validation with Mirage), I’ve looked at just the Ember.js side. In this article, I’ll connect it with Django so that we have an actual backend that’s returning our errors. It builds on top of previous Ember.js code. There are also full Github repositories at the end.

Lets start with Django. We’ll be using Django Rest Framework to generate server side Django.

We have a basic

from __future__ import unicode_literals
from django.db import models

class Registration(models.Model):
        ('male', 'Male'),
        ('female', 'Female'),
        ('unspecified', 'Unspecified')

    firstname = models.CharField(max_length=100)
    lastname = models.CharField(max_length=100)
    submitted = models.DateTimeField(auto_now_add=True)

and an API in

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status

from .models import Registration
from .serializers import RegistrationSerializer

class RegistrationViewSet(viewsets.ViewSet):
    def create(self, request):
        serializer = RegistrationSerializer(
        if serializer.is_valid():
            return Response(, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

One thing to note – we return 400 Error code, instead of 422 that we mocked with Mirage. That is because Ember Django Adapter wraps 400 error to make it compatible with JSON API specification.

All of our business logic of API validation happens in

from rest_framework import serializers

from . models import Registration

class RegistrationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Registration
        fields = ('id', 'firstname', 'lastname')
    def validate_firstname(self, value):
    	if 'john' not in value.lower():
    		raise serializers.ValidationError('First name must be John')
    	return value

    def validate_lastname(self, value):

    	if 'smith' in value.lower():
    		raise serializers.ValidationError("Last name can't be Smith")
    	return value

    def validate(self, data):
    	if data['firstname'] == 'John' and data['lastname'] == 'Doe':
    		raise serializers.ValidationError("Please enter a more original name")

With server side in place, we can extend the previous example Ember.js app. We’ll be using Ember Django Adapter to make things easier.

First of, we need to turn of ember-cli-mirage in config/environment.js. We also set the development URL and API namespace at the same time.

  if (environment === 'development') {
    ENV.APP.API_HOST = 'http://localhost:8000';

    ENV['ember-cli-mirage'] = {
      enabled: false

Another source of problems is that DS.RESTAdapter pluralises api endpoints. So instead of /api/registration/ it posts to /api/registrations/. To make it stop doing that we can define ‘registration’ as uncountable:
(ember generate drf-adapter application)

import DRFAdapter from './drf';
import Inflector from 'ember-inflector';

const inflector = Inflector.inflector;

export default DRFAdapter.extend({});

Controller is still the same:

import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    save() {
      var model = this.get('model'); => {
        // it's a mock, we don't do anything
      }).catch((adapterError) => {
        // we just need to catch error

The main improvement is that template error handling now also displays non-field errors (via model.errors.base):

{{#each model.errors.base as |error|}}
  <span class="errors">{{error.message}}</span>

    <label>First name: {{input value=model.firstname}}</label>
    {{#each model.errors.firstname as |error|}}
      <span class="errors">{{error.message}}</span>
    <label>Last name:
      {{input value=model.lastname}}
    {{#each model.errors.lastname as |error|}}
      <span class="errors">{{error.message}}</span>
  <button {{action 'save'}}>Save</button>

With this in place, form validation errors now work correctly. If server side form validation passes, it also writes data into Data Store.

Ember.js code is in ‘django-api’ branch at
Django code is at

DjangoCamp Ljubljana, lets do it!

Getting back into Camp spirit, we (as in Gašper Ž. and I) thought about doing something for our growing Django community. Since a lot of things that we built runs on Django it feels just right.

What: Django (python framework thingie) community driven unconference for people that are already using Django. It’s not that we don’t like newbie’s, but we’ll invite them to event that is more optimized for them.

Where and when: Kiberpipa, Ljubljana on Saturday, 11th of December 2010

Language of event: Slovenian but you can present in English or Croatian

We plan to limit event to 40-50 people so it doesn’t get complicated with budget and organization. For the same reasons we probably won’t be recording the sessions, so that we can have group discussions and fingers pointing toward laptop displays.

Extra rule is that every participant should prepare a short presentation on something Django related. It can be a full-blown sessions tutorial, GIS Django example project or just a clever middleware hack.

Still interested in attending? Leave your e-mail in this quick form and we’ll keep you updated.

Python SMTP sink server

Debugging email sending in your Web application is always tricky as you need a working SMTP and you also need to watch out that you don’t accidently spam real users (if you’re working on a local copy of real database).

There is a neat one liner that acts as a “sink smtpd” server, meaning that it implements SMTP protocol, so you app can communicate with it, while printing everything it receives on screen:

sudo /usr/lib/python2.6/ -n -c DebuggingServer localhost:25

(via Django Snippets)

Django and YUI time

I’ve been working intensively with Django for last few weeks and even managed to find a few bugs in it and also create a patch or two. Django-unicode branch is working very well for me and I would recommend using it as your main development branch since it solves a lot of problems if you are using unicode data (which often an issue for Slovenian developers).

I have also decided on my Javascript toolkit of choice. I’m going with Yahoo user interface library (YUI) because of documentation and great browser support. On top of that, I’m amazed at their cheat sheets. I’ve got mine laminated.

Laminated YUI cheat sheets

Django cleaned_data

Just a quick note to the few of you who are also tracking Django trunk. Today Django team changed clean_data in newforms to cleaned_data because of possible namespace clash. To port the new version you will just need to do some find and replace.

More important implication of this change is that now 0.96 newforms code is incompatible with Django trunk.

More about this in Django wiki