2016-06-24 4 views
1

に複数のフィールドに除外しますか?重要なことの1つは、後で終了する別のプレミアムがない場合にのみ、プレミアムが欲しいということです。でも、サイトごとにです。したがって、ユーザーがgroceries.comに別のプレミアムを持っている場合、明日終了するものは返されませんが、officeupplies.comに別のプレミアムがない場合は、となります。Djangoは、このようないくつかのコードを考えると、サブクエリ

(それが実際に動作しないの前にそれは私が完了するために必要な部分です...コメント付きで行を注意してください。)

私はORMの外にこれを行う方法を考え出すことができますが、私は思います数ヶ月でデータベースベンダーを切り替えることを計画しているので、ORMソリューションが本当に好きなので、できるだけ未処理のSQLを避けようとしています。ここで

は私が取得したいのですが行動のためのテストです:

class PremiumTest(TestCase): 

    def test_gets_ending_premiums(self): 
     today = date(2020, 6, 5) 
     tomorrow = today + timedelta(days=1) 
     next_year = today + timedelta(days=366) 
     groceries = Site.objects.create(domain='groceries.com') 
     catvids = Site.objects.create(domain='catvids.com') 
     dave = User.objects.create_user('dave') 
     sally = User.objects.create_user('sally') 
     Premium.objects.create(user=dave, site=groceries, end=tomorrow) 
     Premium.objects.create(user=dave, site=groceries, end=next_year) 
     Premium.objects.create(user=dave, site=catvids, end=tomorrow) 
     Premium.objects.create(user=sally, site=groceries, end=tomorrow) 
     Premium.objects.create(user=sally, site=catvids, end=tomorrow) 
     Premium.objects.create(user=sally, site=catvids, end=next_year) 

     ending_premiums = get_ending_premiums(today) 
     ending = set((p.user, p.site) for p in ending_premiums) 

     self.assertNotIn((dave, groceries), ending) 
     self.assertIn((dave, catvids), ending) 
     self.assertIn((sally, groceries), ending) 
     self.assertNotIn((sally, catvids), ending) 
     self.assertEqual(2, len(ending_premiums)) 

答えて

0

私は...これを作ってみたそれは、いくつかの生のSQLを持っているが、それはまだ(通常のクエリセットメソッドとクエリセットを返します。それは良い方法がない場合は疑問に思っ明らかに非推奨QuerySet.extra()方法)まだ

def get_ending_premiums(day=None): 
    """Get a queryset of Premiums for which a user has none following.""" 
    if day is None: 
     day = date.today() 
    tomorrow = day + timedelta(days=1) 

    ending_premiums = Premium.objects.filter(
     end=tomorrow, 
    ).extra(
     where=['NOT EXISTS (SELECT NULL FROM premium_premium child where premium_premium.site_id = site_id AND premium_premium.user_id = user_id AND end > %s)'], 
     params=[tomorrow], 
    ) 
    return ending_premiums 

を使用しているが...

関連する問題