Как фильтровать модель в просмотре списка
У меня есть страница, которая отображает список интервьюеров и некоторую важную информацию о каждом пользователе. Одна из вещей, которую я хочу, чтобы она показывала, это количество пользователей, которые были опрошены этим конкретным интервьюером. Я написал представление следующим образом:
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 theUsermodel to theScientificInfomodel 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 therelation tointerviewerinterviews.