我正在为Family
对象开发通用ListView
。每个Family
都具有一个employee_user
和partner_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中,我找不到一种简洁的方法来执行此操作。关于如何在仍通过这些测试的同时重构此代码的任何建议?