def test_m2m_prefetch(self):
        with self.assertNumQueries(3):
            q = FastQuery(User.objects.all())
            q.prefetch_related(FastPrefetch('groups', Group.objects.all()))
            result = q.execute()

        self.assertTrue(all([_['groups'] for _ in result]))
        self.assertTrue(isinstance(result[0]['groups'], list))
        self.assertEquals(set(['id', 'name']),
                          set(result[0]['groups'][0].keys()))
    def test_fk_prefetch(self):
        with self.assertNumQueries(2):
            q = FastQuery(User.objects.all())
            q.prefetch_related(FastPrefetch('location',
                                            Location.objects.all()))
            result = q.execute()

        self.assertTrue(all([_['location'] for _ in result]))
        self.assertEquals(set(['blob', 'id', 'name']),
                          set(result[0]['location'].keys()))
    def test_m2o_prefetch(self):
        with self.assertNumQueries(2):
            q = FastQuery(Location.objects.all())
            q.prefetch_related(FastPrefetch('user_set', User.objects.all()))
            result = q.execute()

        self.assertTrue(all(['user_set' in obj for obj in result]))
        location = six.next(
            (o for o in result if o['user_set'] and len(o['user_set']) > 1))

        self.assertIsNotNone(location)
        self.assertEquals(self._user_keys(),
                          set(location['user_set'][0].keys()))
    def test_o2o_prefetch(self):
        # Create profiles
        for i in range(1, 4):
            Profile.objects.create(user=User.objects.get(pk=i),
                                   display_name='User %s' % i)

        with self.assertNumQueries(2):
            q = FastQuery(Profile.objects.all())
            q.prefetch_related(FastPrefetch('user', User.objects.all()))
            result = q.execute()

        self.assertTrue(all([_['user'] for _ in result]))
        self.assertEquals(self._user_keys(), set(result[0]['user'].keys()))
    def test_reverse_o2o_prefetch(self):
        # Create profiles
        for i in range(1, 4):
            Profile.objects.create(user=User.objects.get(pk=i),
                                   display_name='User %s' % i)

        with self.assertNumQueries(2):
            q = FastQuery(User.objects.all())
            q.prefetch_related(FastPrefetch('profile', Profile.objects.all()))
            result = q.execute()

        self.assertTrue(all(['profile' in _ for _ in result]))
        user = sorted(result, key=lambda x: 1
                      if x['profile'] is None else 0)[0]
        self.assertEquals(
            set(['display_name', 'user_id', 'id', 'thumbnail_url']),
            set(user['profile'].keys()))