我似乎无法弄清楚。我的观点接受了Team.id
的参数,我想返回一个上下文对象,其中每个User
对象在User.profile.team
中具有某个值,并且关联的日期从Reports
开始。我感觉自己开始走上正确的道路,但缺少一些东西。模板的输出包含了我要获取的所有数据,但没有以可以逻辑显示的方式。
基本上,我使用的模型类似于以下内容:
class Reports(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.PROTECT)
product = models.CharField(max_length=15)
apps_activated = models.IntegerField(blank=True, null=True)
prem_submitted = models.DecimalField(max_digits=30, decimal_places=2)
class Team(models.Model):
name = models.CharField(max_length=255)
leader = models.ForeignKey(User,on_delete=models.PROTECT)
扩展的用户个人资料:
class Profile(models.Model):
COORDINATOR = 1
LEADER = 2
ADMIN = 3
ROLE_CHOICES = (
(COORDINATOR, 'Coordinator'),
(LEADER, 'Leader'),
(ADMIN, 'Admin'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.PROTECT,null=True)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
我认为返回所需数据最接近的是以下内容:
team = 1
team_name = Team.objects.get(id=team)
team_users = User.objects.filter(profile__team=team).all()
team_stats = []
for user in team_users:
team_stats.append(Reports.objects.filter(user_id=user.id))
使用如下模板:
{% block content %}
<h1>{{ team }}</h1>
<ul>
{% for user in team_users %}
<li><a href="/reports/user/{{ user.id }}">{{ user.first_name }} {{ user.last_name }}</a></li>
{% endfor %}
</ul>
<ul>
{% for stat in team_stats %}
<li>
{% for line in stat %}
{{ line.product }} {{ line.type }} #etc #etc
{% endfor %}
</li>
{% endfor %}
</ul>
{% endblock %}
我以为我对prefetch_related()
感兴趣,但无法解决。理想情况下,我只需要将一个上下文对象返回到模板即可。
编辑:
如果更清楚,此查询将返回我尝试传递给模板的结果:
select auth_user.first_name, auth_user.last_name, r.product, r.apps_activated, r.prem_submitted, r.conversion_percentage, r.type
from auth_user
join home_profile
on auth_user.id = home_profile.user_id
join reports_reports as r
on auth_user.id = r.user_id
where home_profile.team_id = 1
返回如下行:
first_name-last_name-product-apps_activated-prem_submitted-conversion_rate-type
user_1-user_1_last-product_1-693-139764.00-53.86-type1
user_1-user_1_last-product_2-74-27400.10-0.00-type1
user_1-user_1_last-product_3-102-19782.00-47.00-type2
user_2-user_2_last-product_1-7-2437.70-0.00-type2
user_2-user_2_last-product_2-52-10608.00-42.54-type3
user_2-user_2_last-product_3-260.40-0.00-type3
答案 0 :(得分:2)
潜在解决方案1 :
因此,我将执行以下操作。在您的user
模型中更改Reports
以显式链接到Profile
(进而链接到用户)
class Reports(models.Model):
profile = models.ForeignKey(Profile, null=True, on_delete=models.PROTECT)
product = models.CharField(max_length=15)
apps_activated = models.IntegerField(blank=True, null=True)
prem_submitted = models.DecimalField(max_digits=30, decimal_places=2)
您似乎正在寻找可能正在寻找类似select_related()
查询的对象,为配置文件添加了额外的ForeignKey
字段:
reports = Reports.objects.select_related('profile')
您可以通过str(reports.query)
来检查生成的SQL,这将导致您在问题中所概述的内容。
然后,将返回的游标值转换为适当的ORM模型实例,以便当您遍历这些reports
时,可以通过它们自己的对象访问相关表的值。但是,沿着预选的前向关系进行的这些访问不会导致额外的数据库命中:
{% for report in reports %}
{{ report.profile.user.username }}
{{ report.product }}
# ...
{% endfor %}
让我知道您的生活如何,如果我们不能集体讨论一种更合适的解决方案,
潜在解决方案2 :
也许另一种解决方案,也许是两者中最简单的一种,就是在您的Profile
模型中与Reports
建立一个ManyToMany关系:
class Profile(models.Model):
COORDINATOR = 1
LEADER = 2
ADMIN = 3
ROLE_CHOICES = (
(COORDINATOR, 'Coordinator'),
(LEADER, 'Leader'),
(ADMIN, 'Admin'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.PROTECT,null=True)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
reports = models.ManyToManyField(Reports, ...)
然后,您应该可以在模板中循环users
:
{% for user in users %}
{% for report in user.reports.all %}
{{ report.product }}
{% endfor %}
{% endfor %}