以下是我的模特:
class Activity(models.Model):
title = models.CharField(blank=False, max_length=100)
description = models.TextField(blank=False)
class UserActivityWork(models.Model):
activity = models.ForeignKey(Activity)
user = models.ForeignKey(User)
hours_worked = models.FloatField()
comment = models.TextField()
示例数据将是“攀登珠穆朗玛峰”的活动,每个用户都可以输入他们花了多长时间和评论。
以下是我的问题:如何显示所有活动的列表,如果用户输入了该活动的数据,则显示活动旁边的相关详细信息?
到目前为止,我已经考虑过:
非常感谢任何见解!
答案 0 :(得分:1)
假设您可以在模板中访问2个查询集(例如,活动和user_activities)
一种天真的方式是迭代每个活动,然后遍历每个用户活动。
{% for activity in activities %}
{{ activity.title }}
{% for user_activity in user_activities %}
{% ifequal user_activity.activity activity %}
Display userdata
{% endifequal %}
{% endfor %}
{% endfor %}
可以使用点(。)
在模板中执行字典查找从技术上讲,当模板系统遇到一个点时,它会按以下顺序尝试以下查找:
- 字典查找
- 属性查找
- 方法调用
- 列表索引查找
另一种选择是创建custom template tag。您可以像以前一样遍历活动列表,然后将活动以及user_activity列表或用户传递给标记以执行查找并呈现所需的数据。
答案 1 :(得分:0)
感谢Gerry的提示。我发现按照你的建议编写自定义模板标签是要走的路。 以下是血腥的细节,万一有人偶然发现了这一点。
在view方法中,我发布了一个字典“user_activity_status”,其中包含activity.id的键和UserActivityWork对象的值,用于登录用户对该活动的工作
这是模板的相关部分。基本上这将添加一个值为
的变量“map_value”getattr(user_activity_status[activity.id], "comment")
这是模板:
{% load *file-name-of-the-templatetag-file* %}
{% access_map_method user_activity_status activity.id comment %}
{% if map_value %}
{{ map_value }}
{% else %}
get working sucka!
{% endif %}
这是模板标签文件的一部分(有关如何设置的详细信息,请参阅Gerry的链接)
from django import template
register = template.Library()
@register.tag(name="access_map_method")
def do_access_map_method(parser, token):
try:
tag_name, dict_name , key_name, method_name = token.contents.split()
except ValueError:
msg = '%r tag requires three arguments' % token.contents[0]
raise template.TemplateSyntaxError(msg)
return MapNode(dict_name , key_name, method_name)
class MapNode(template.Node):
def __init__(self, dict_name, key_name, method_name):
self.dict_var = template.Variable(dict_name)
self.key_var = template.Variable(key_name)
self.method_name = method_name
def render(self, context):
try:
dict_obj = self.dict_var.resolve(context)
key_obj = self.key_var.resolve(context)
if key_obj in dict_obj.keys():
if self.method_name:
context['map_value'] = getattr(dict_obj[key_obj], self.method_name)
else:
context['map_value'] = dict_obj[key_obj]
else:
context['map_value'] = ''
except template.VariableDoesNotExist:
context['map_value'] = ''
return ''