Как фильтровать модель в просмотре списка

У меня есть страница, которая отображает список интервьюеров и некоторую важную информацию о каждом пользователе. Одна из вещей, которую я хочу, чтобы она показывала, это количество пользователей, которые были опрошены этим конкретным интервьюером. Я написал представление следующим образом:

class ManagerUsers(ListView):
model = User
template_name = 'reg/manager-users.html'
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['scientific_interviewers'] = User.objects.filter(role='theory_interviewer').all()

    context['interviewed_number'] = len(ScientificInfo.objects.filter(user__role='applicant', is_approved=True, interviewer=?????))

поле interviewer должно быть равно пользователю этого объекта, но я не знаю, что именно делать. На выходе должно получиться что-то вроде этого: объект 1 : имя пользователя, другая информация пользователя, номер_интервьюера пользователя ....

вот мои модели:

USER_ROLE_CHOICES = (('0', 'applicant'),
                 ('1', 'theory_interviewer'),)

class User(AbstractUser):
id = models.AutoField(primary_key=True)
role = models.CharField(max_length=25, null=True, choices=USER_ROLE_CHOICES, default=USER_ROLE_CHOICES[0][0])
username = models.CharField(unique=True, max_length=13)
first_name = models.CharField(max_length=32, null=True, default=None)
last_name = models.CharField(max_length=64, null=True, default=None)

class ScientificInfo(models.Model):
id = models.AutoField(primary_key=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user')
interviewer = models.OneToOneField(User, on_delete=models.CASCADE, related_name='interviewer')
is_approved = boolean field

You can override the .get_queryset() method [Django-doc] to return only the interviewers. By using .annotate(…) [Django-doc] you can add an extra attribute to these Users:

from django.db.models import Count

class ManagerUsersView(ListView):
    model = User
    context_object_name = 'scientific_interviewers'
    template_name = 'reg/manager-users.html'
    
    def get_queryset(self):
        return super().get_querset().filter(
            role='1'
        ).annotate(
            interviewed_number=Count('interviewer', filter=Q(interviewer__user__role='0', interviewer__is_approved=True))
        )

У User, возникающих из этого набора запросов, будет дополнительный атрибут .interviewed_number с количеством одобренных ScientificInfo, где этот пользователь был interviewer.


Примечание: В Django представления, основанные на классах (CBV), часто имеют суффикс …View, чтобы избежать столкновения с именами моделей. Поэтому вы можете переименовать класс представления в ManagerUsersView, вместо ManagerUsers.


Note: The related_name=… parameter [Django-doc] is the name of the relation in reverse, so from the User model to the ScientificInfo model in this case. Therefore it (often) makes not much sense to name it the same as the forward relation. You thus might want to consider renaming the interviewer relation to interviews.

Вернуться на верх