重构Django布尔查询

时间:2018-07-20 18:29:36

标签: python django

我正在为Family对象开发通用ListView。每个Family都具有一个employee_userpartner_user的一对一字段,而它们又具有一个Profile模型的一对一字段(带有一个相关名称user_profile),其中包含布尔值using_app。如果员工或伴侣正在使用该应用程序,则认为一个家庭正在使用该应用程序。

当前,我有以下get_queryset()方法

def get_queryset(self):
    queryset = super().get_queryset()
    if app:
        using_app = app == 't'
        if using_app:
            queryset = queryset.filter(
                Q(employee_user__user_profile__using_app=using_app) |
                Q(partner_user__user_profile__using_app=using_app))
        else:
            queryset = queryset.filter(
                Q(employee_user__user_profile__using_app=using_app) &
                Q(partner_user__user_profile__using_app=using_app))

    return queryset

这使此ListView通过了以下测试(使用factory_boy测试夹具):

from django.test import TestCase
from django.urls import reverse

from dashboard.tests.utils import AccountMixin
from lucy_web.test_factories import FamilyFactory, UserFactory


class FamilyUsingAppTest(AccountMixin, TestCase):
    def setUp(self):
        self.login_user(UserFactory(is_superuser=True))

    def test_filter_families_using_app(self):
        family = FamilyFactory(
            employee_user=UserFactory(user_profile__using_app=True),
            partner_user=UserFactory(user_profile__using_app=False))

        self.assertIs(family.using_app, True)

        response = self.client.get(
            path=reverse('dashboard:families'),
            data={'app': 't'})

        self.assertEqual(response.context['object_list'].count(), 1)
        self.assertTrue(response.context['object_list'].first() == family)

    def test_filter_families_not_using_app(self):
        family = FamilyFactory(
            employee_user=UserFactory(user_profile__using_app=True),
            partner_user=UserFactory(user_profile__using_app=False))

        response = self.client.get(
            path=reverse('dashboard:families'),
            data={'app': 'f'})

        self.assertEqual(response.context['object_list'].count(), 0)

但是,get_queryset方法在if... else子句中包含一些代码重复,并且我希望通过使用Queryset.annotate()来重构它。但是,从Django Boolean Queryset Filter Not Working中,我找不到一种简洁的方法来执行此操作。关于如何在仍通过这些测试的同时重构此代码的任何建议?

0 个答案:

没有答案