Brown University Homepage Brown University Library

Python/Django Quicktips: Ordered JSON Load and Django Email Testing

Ordered JSON Load

Recently, I had the need to load some data from our JSON Item API in the same order it was created. When we construct the data, we use an OrderedDict to preserve the order and then we dump it to JSON.

In [1]: import json
In [2]: from collections import OrderedDict
In [3]: info = OrderedDict()
In [4]: info['zebra'] = 1
In [5]: info['aardvark'] = 10

In [6]: info
 Out[6]: OrderedDict([('zebra', 1), ('aardvark', 10)])

In [7]: json.dumps(info)
 Out[7]: '{"zebra": 1, "aardvark": 10}'

By default, though, the JSON module loads that data into a regular dict, and the order is lost.

In [8]: json.loads(json.dumps(info))
 Out[8]: {u'aardvark': 10, u'zebra': 1}

What’s the solution? Tell the json module to load the data into an OrderedDict:

In [9]: json.loads(json.dumps(info), object_pairs_hook=OrderedDict)
 Out[9]: OrderedDict([(u'zebra', 1), (u'aardvark', 10)])

Django email testing

Some of our django projects send out notification emails, to a user or a site admin. Django has the handy mail_admins and send_mail functions, but what if you want to test that the email was sent?

Django makes it easy to unit-test the emails – its test runner automatically uses a dummy email backend. Then you can import the mail outbox and verify its contents. Here’s a code snippet that tests an email being sent:

from django.core.mail import send_mail
def send_email():
    send_mail('Blog post', 'Test for the blog post',  digital_technologies@brown.edu',
 ['public@example.com'], fail_silently=False)

from django.test import SimpleTestCase
from django.core import mail

class TestEmail(SimpleTestCase):

   def test_email(self):
       send_email()
       self.assertEqual(len(mail.outbox), 1)
       self.assertEqual(mail.outbox[0].subject, 'Blog post')
       self.assertEqual(mail.outbox[0].body, 'Test for the blog post')

Note: you can’t import outbox from django.core.mail and check that len(outbox) == 1. This is because outbox is just a list, and it gets re-initialized to a new list before each test case.