получение КОЛИЧЕСТВА уникальных значений в наборе запросов django с помощью цикла for

#python #django #django-rest-framework #django-queryset

#python #django #django-rest-framework #django-queryset

Вопрос:

новичок здесь в django и django-rest-framework. Могу ли я спросить, возможно ли получить количество уникальных значений в цикле for? Я столкнулся с этим вариантом использования, когда мне нужно получить количество всех уникальных значений в наборах запросов цикла for. Реализация заключалась в том, чтобы выполнить цикл внутри наборов запросов и поместить в список все уникальные объекты и вернуть len() этого. Проблема с этой реализацией заключалась в том, что она вызывала множественные запросы к базе данных в django-debug-toolbar. Пожалуйста, смотрите код ниже для справки. Есть ли другой способ реализовать это? Заранее благодарю вас.

 activity_list = []

classes = Class.objects.all()

for class in classes:
    student_activities = class.studentactivity_set.all()

    for activity in student_activities:
        if activity not in activity_list:
            activity_list.append(activity)

return len(activity_list)
  

Ответ №1:

Самый простой способ — превратить это в набор, а затем использовать len() функцию на наборе. Вы также можете добавлять элементы непосредственно в набор, что должно избавить вас от выполнения каких-либо дополнительных сравнений.

 >>> lst = [1, 2, 3, 4, 4]
>>> len(lst)
5
>>> st = set(lst)
>>> len(st)
4
>>> st.add(5)
>>> len(st)
5
>>> st.add(5)
>>> len(st)
5
  

Комментарии:

1. Спасибо за предложение, но есть ли другой способ избежать цикла for?

2. Это избавляет от внутреннего цикла for. Вы также хотите избавиться от внешнего цикла for?

3. Как это удаляет внутренний цикл for? Простите меня, поскольку я новичок. Спасибо

Ответ №2:

Вы можете сделать это с помощью Django ORM:

 activity_count = (StudentActivity.objects
  .exclude(related_class=None) # exclude not linked activities
  .count() # count unique items
)
  

Я не тестировал этот код, пожалуйста, сделайте это самостоятельно.

Комментарии:

1. Привет, будет ли это предоставлять activity_count для каждого класса? Вот почему я зацикливаю это, чтобы я мог получать каждое действие для каждого класса.

2. Я ориентировался на ваш пример кода. Вы получаете количество экземпляров StudentActivity, которые связаны хотя бы с одним экземпляром класса. Правильно ли это? Или вам нужно другое поведение? Если к классу относятся два или более действия, существует несколько разных элементов activity. По какому атрибуту вы хотите идентифицировать их как дубликаты? Было бы неплохо, если бы вы предоставили свои классы моделей.

3. Ну, мне нужно получить количество уникальных действий для каждого класса для каждого учащегося. Это необходимо, поскольку я проверяю все оцененные действия по сравнению с действиями, которые еще не оценены. Хотя я не ставлю filter() как просто хочу иметь простой пример кода.

4. Пример, если я напечатаю набор запросов, вы получите набор запросов <[1, 2, 3]> в первом классе, затем во втором классе я получу набор запросов<[3, 4]>, мне нужно получить уникальные идентификаторы 1,2,3,4, поскольку эти значения активности уже оценены, и первый класс не был оценен по идентификаторам активности 4, в то время как второй класс не был оценен по идентификаторам активности 1 и 2