Answer the question
In order to leave comments, you need to log in
Is it possible to use an indirect access to the context variable in the template?
The essence of the task - it is necessary to display a table with the totals by category. For example:
Each user selects their categories. For each category, you can add several features. At the intersection of the user and category, the number of features is displayed.
To build a table, I use an SQL query and create a context variable.
sql = 'select pu.id, pu.user_id, '
for section in project.sections.all():
sql += ' (select COUNT(*) from section ...
sql += ' where pus.section_id = ' str(section.id)
sql += ' and pus.id = pusp.profile_user_section_id ) count_in_section_' + str(section.id) + ','
sql += ' u.first_name, u.last_name '
sql += ' from ...'
sql += ' where ... '
users_list = list(project.profile_users.raw(sql, params=[project_id]))
context = {'project': project,
'users_list': users_list,
}
return render(request, template, context)
...
{% for item in users_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.first_name }}</td>
<td>{{ item.last_name }}</td>
{% for section in project.sections.all %}
<td>
<b> {{ column_name_1 }}</b> <!-- ??? Нужна косвенная адресация -->
</td>
{% endfor %}
</tr>
{% endfor %}
...
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
# Create your models here.
class Section(models.Model):
name = models.CharField(max_length=25, verbose_name=_('Категория'))
class Criterion(models.Model):
name = models.CharField(max_length=250, verbose_name=_('Критерий'))
class ProfileUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name=_('Пользователь'), unique=True)
user_info = models.CharField(max_length=100)
class Project(models.Model):
profile_users = models.ManyToManyField(ProfileUser, verbose_name=_('Участники'), through='ProjectProfileUser')
class ProjectProfileUser(models.Model):
profile_user = models.ForeignKey(ProfileUser, on_delete=models.CASCADE, verbose_name=_('Пользователь'))
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name=_('Проект'))
sections = models.ManyToManyField(Section, through='ProfileUserSection', verbose_name=_('Категории'))
class ProfileUserSection(models.Model):
project_profile_user = models.ForeignKey(ProjectProfileUser, on_delete=models.CASCADE, verbose_name=_('Пользователь'))
section = models.ForeignKey(Section, on_delete=models.CASCADE, verbose_name=_('Категория'))
сriterions = models.ManyToManyField(Criterion, verbose_name=_('Критерии'), through='ProfileUserSectionCriterion')
class ProfileUserSectionCriterion(models.Model):
criterion = models.OneToOneField(Criterion, on_delete=models.CASCADE, verbose_name=_('Критерий'))
profile_user_section = models.ForeignKey(ProfileUserSection, on_delete=models.CASCADE, verbose_name=_('Категория'))
Answer the question
In order to leave comments, you need to log in
If I understand correctly, each row corresponds to one `ProfileUser`, and each column to one `Section`. And not all, but only those `Section` that belong to the current project. Each cell is therefore the number of all `ProfileUserSection` objects corresponding to the corresponding `ProfileUser` and `Section`. Do I get it right?
Addressing in the template is not possible, this is a deliberate limitation. Therefore, you will have to transfer a ready-made matrix of cells to the template. Well, for example, as follows - I can not vouch for the optimality, however.
sections = list(Section.objects.filter(project=project, ...))
users = list(ProfileUser.objects.filter(...))
cells = [[user] + [
ProfileUserSection.objects.filter(user=user, section=section).count() for section in sections
] for user in users]
context = {
'sections': sections,
'rows': cells
}
{% for row in rows %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question