Джанго исключает прошлые отношения со многими? - PullRequest
0 голосов
/ 08 марта 2012

У меня возникли проблемы с Django, и я выполняю исключение после запроса многие ко многим.

Следующие четыре таблицы имеют значение:

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, ...

Очевидно, что каждый TestCase может существовать в большом количестве прогонов, каждый прогон может иметь один статус, и каждый тестовый случай может иметь одну категорию, хотя в каждой категории может быть большое количество тестовых случаев.

Цель состоит в том, чтобы получить количество тестовых случаев для категории, которая провалилась, за определенный промежуток времени, но там, где нет сбоев «разработки». Это хорошо структурированные имена:

PASS-DEV
FAIL
FAIL-DEV
...

Раньше у меня было много запросов для этого, но у нас возникали проблемы с производительностью. Поэтому мы пытаемся объединить его в один запрос:

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')

Это говорит о том, что я сталкиваюсь с ошибкой в ​​Django или делаю что-то не «правильное» для django. Что это?

Ответ ниже неправильный, но приведите меня к правильному ответу:

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 Ответ

1 голос
/ 08 марта 2012

Поскольку вы выполняете запрос на TestCaseCategory, исключение исключает категорию, а не отдельные связанные элементы, когда есть совпадение. Другими словами, если в категории есть хотя бы один TestCaseRun со статусом, содержащим «dev», вся категория исчезнет из ваших результатов.

Однако, в любом случае, это неправильный подход. Вы должны думать с точки зрения того, с чем вы на самом деле работаете. Требуется количество тестовых наборов по категориям, но это означает, что речь идет о тестовых случаях, а не категориях.

Попробуйте:

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, поэтому вы не можете использовать его для чего-либо другого, но у вас будет количество.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...