django-denormalize / denormalize / tests /

from ..models import DocumentCollection
import os
from pprint import pprint
import logging
log = logging.getLogger(__name__)

# TODO: check if the SQL queries are efficient (all data should be fetched in one query)

class BookCollection(DocumentCollection):
    model = None
    name = "books"
    select_related = ['publisher', 'extra_info']
    prefetch_related = ['chapter_set', 'authors', 'tags', 'publisher__links',
        'category_set', 'publisher__tags']
    exclude = ['authors__email', 'summary']
    add_model_name = True

    def dump_obj(self, model, obj, path):
        # Customization: for tags, use the name string as the representation
        if == 'Tag':
        # Here only the url
        if == 'PublisherLink':
            return obj.url
        return super(BookCollection, self).dump_obj(model, obj, path)

class CollectionTestMixin(object):
    def setUpClass(cls):
        cls.objs = cls.models.create_test_data()

    def tearDownClass(cls):

    def test_dump(self):
        bookcol = self.collection()
        doc = bookcol.dump(self.objs['book'])

        # Basic fields
        self.assertTrue('id' in doc)
        self.assertTrue('title' in doc)
        self.assertFalse('summary' in doc, "The summary was not excluded")
        self.assertTrue('year' in doc)
        self.assertTrue('created' in doc)
        self.assertEqual(doc['id'], self.objs['book'].id)

        # Relational fields
        self.assertTrue('publisher' in doc, doc)
        self.assertEqual(doc['publisher']['name'], u"O'Reilly")
        self.assertTrue('authors' in doc, doc)
        self.assertEqual(len(doc['authors']), 1)
        self.assertTrue('chapter_set' in doc, doc)
        self.assertEqual(len(doc['chapter_set']), 7)

        # Other expectations

        # - Tags are pure strings
        self.assertItemsEqual(doc['tags'], [u'cooking', u'geeks', u'technology'])

        # - ForeignKeys not explicitly followed are included as a pure id
        chapter = doc['chapter_set'][0]
        # TODO: we should probably omit it if it's the relation we just followed
        self.assertTrue('book_id' in chapter,
            "If a FK is not followed, its id will be included")

        # - Author emails are excluded
        author = doc['authors'][0]
        self.assertFalse('email' in author, "The author email was not excluded")

    def test_dump_collection(self):
        bookcol = self.collection()
        docs = list(bookcol.dump_collection())
        self.assertEqual(len(docs), 2)
        if 'pprint' in os.environ:

    def test_get_related_models(self):
        bookcol = self.collection()
        deps = bookcol.get_related_models()
        if 'pprint' in os.environ:
        self.check_related_models(bookcol, deps)