2012-03-07 10 views
0

私はDjangoにいくつかの問題があり、多くのクエリから過去の除外を実行しています。Djangoは過去の1対多数の関係を除外しますか?

次の4つの表は関係:

Status - name, id 
TestcaseCategory - category, id 
Testcase - category (Foreign key to TestcaseCategory), id, name... 
TestcaseRun - testcase (Foreign key to Testcase), id, status (Foreign key to Status), start_date, end_date, ... 

を明らかに各テストケースの実行が多数存在することができる、それぞれの実行は、1つのステータスを持つことができ、かつ大規模な存在かもしれませんが、各テストケースは、一つのカテゴリを持つことができますカテゴリごとのテストケースの数

目標は、時間枠内で失敗したカテゴリごとのテストケースの数を取得することですが、「開発」の失敗はありません。これらはうまく構成された名前です:

PASS-DEV 
FAIL 
FAIL-DEV 
... 

私はこれを行うために多くのクエリを使用していましたが、パフォーマンスの問題で終わった。そのため、我々は、単一のクエリにそれをconsilidateしようとしている:これは私がDjangoのバグを打つか、ジャンゴのための「正しい」ではない何かをやっている示唆

excludeArgs = {"testcase__testcaserun__status__name__icontains": "dev"} 
filterArgs = {"testcase__testcaserun__status__name__icontains": "fail", 
       'testcase__testcaserun__end_date__gte': start, 
       'testcase__testcaserun__end_date__lte': end} 
categoryData = models.TestCaseCategory.objects.all() 
categoryData = categoryData.filter(**filterArgs) 
# Data exists here fine 
categoryData = categoryData.exclude(**excludeArgs) 
# Huh? Exclude has removed all of our results, when we expect there to be results! 
# This happens even if I move exclude before the filter. 
# if we did have anything left, we would do the following to get only the values we want: 
categoryData = categoryData.annotate(fail=Count('testcase__testcaserun')) 
categoryData = categoryData.values('category', 'fail') 

。どちらですか?

以下の答えが間違っているが、正しい答えに私を導く:

あなたが TestCaseCategoryでクエリを実行しているので
categoryData = models.TestCaseRun.objects.\ 
exclude(status__name__icontains='dev').\ 
filter(status__name__icontains='fail', end_date__range=(start, end)).\ 
values('testcase__category').annotate(fail=Count('id')).order_by() 

答えて

1

、除外カテゴリを除外されるが、個々の関連する項目がありますない時はいつでも一致。つまり、カテゴリに「dev」を含むステータスのあるTestCaseRunが少なくとも1つある場合は、カテゴリ全体が結果から除外されます。

しかし、これはとにかく間違ったアプローチです。あなたが実際に働いていることの観点から考える必要があります。カテゴリ別にテストケースの数を求めていますが、それはカテゴリではなくテストケースについてのことです。

試してみてください。

TestCase.objects.\ 
    exclude(testcaserun__status__icontains='dev').\ 
    filter(testcaserun__status__icontains='fail', testcaserun__end_date__range=(start, end)).\ 
    values(category).annotate(Count('id')).order_by() 

重要な部分がvalues(category).annotate(Count('id')).order_by()ビットです。それはカテゴリ別にテストケースをグループ化し、各グループに含まれるテストケースの数をカウントします。結果はValuesQuerySetで実際のQuerySetではなく、他のものに使用することはできませんが、あなたはあなたのカウントを取得します。

+0

上記は間違っていますが、私が欲しいものについて正しい答えに導きます。 私は質問に適切なコードを入れます。 –