Post archive for September 2010

Simplifying the Testing of Unmanaged Database Models in Django

September 24 2010 by Tobias McNulty

Sometimes, when building a web application in Django, one needs to connect to a legacy database whose tables already exist. To support this use case, Django has the concept of "unmanaged models," which let you connect the Django ORM to tables that it assumes to exist (and not attempt to create).

This can make automated testing---which is something we take seriously at Caktus---rather difficult, because you might not have the SQL on hand to create an empty copy of the legacy database for testing purposes. One solution is to automatically set all your unmanaged models to "managed" during a test run, so that Django will happily create the tables for you. Typically this is enough to allow you to add sample data to the database and write tests as you would for any other model in Django. We've also found the approach to work especially well for database views (which typically are manifested as unmanaged models in Django), because it may be easier to test the code that uses the view by treating it as a table during automated testing.

There's a great snippet available for doing this, but the code is lengthly and and basically requires copying and pasting a large portion of the existing test runner in Django. Django 1.2, however, introduces a new class-based test runner that's much better suited for small modifications to the testing process like this.

To give it a try, I wrote a short piece of code that accomplishes this---making all unmanaged models in your Django project "managed" for the duration of the test run:

from django.test.simple import DjangoTestSuiteRunner


class ManagedModelTestRunner(DjangoTestSuiteRunner):
    """
    Test runner that automatically makes all unmanaged models in your Django
    project managed for the duration of the test run, so that one doesn't need
    to execute the SQL manually to create them.
    """
    def setup_test_environment(self, *args, **kwargs):
        from django.db.models.loading import get_models
        self.unmanaged_models = [m for m in get_models()
                                 if not m._meta.managed]
        for m in self.unmanaged_models:
            m._meta.managed = True
        super(ManagedModelTestRunner, self).setup_test_environment(*args,
                                                                   **kwargs)

    def teardown_test_environment(self, *args, **kwargs):
        super(ManagedModelTestRunner, self).teardown_test_environment(*args,
                                                                      **kwargs)
        # reset unmanaged models
        for m in self.unmanaged_models:
            m._meta.managed = False

Enjoy! Don't hesitate to comment with any questions or concerns.

Caktus Consulting Group Seeks Two Python/Django Web Developers

September 03 2010 by Tobias McNulty

I'm delighted to announce that Caktus is looking for two Python and/or Django web developers to join our team on a contract or part-time basis, with the potential for full-time work in the future.

Caktus builds custom web applications for local and remote clients using a variety of open-source technologies. We are a small team based in the Chapel Hill/Carrboro area of North Carolina (currently residing in Carrboro Creative Coworking). We believe in face-to-face contact, both with clients and amongst ourselves, and employ agile development techniques that emphasize teamwork and collaboration. We encourage you to meet the team and learn more about what we do.

We're looking for two experienced Python and/or Django web developers who enjoy working on a team and are excited to work on new projects. We have a preference for local candidates, but will consider all submissions. Your work will involve creating and integrating Django apps, working on existing Django projects, deployment, and database work.

You will be working in Linux (Debian-flavor) production environments with Apache and WSGI. Python and relational database experience is required. Django experience is a (big) plus. HTML/CSS and JavaScript experience are also a must, and jQuery is a plus.

If you're interested in one of these positions, please send us your resume, some sample Python code that you wrote, and links to any open-source projects you've contributed to. We're looking forward to meeting you!