Django问题:如何获取与域对象相关的用户特定信息?

时间:2009-05-28 03:08:33

标签: django django-templates

以下是我的模特:

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()

示例数据将是“攀登珠穆朗玛峰”的活动,每个用户都可以输入他们花了多长时间和评论。

以下是我的问题:如何显示所有活动的列表,如果用户输入了该活动的数据,则显示活动旁边的相关详细信息?

到目前为止,我已经考虑过:

  • 创建一个字典 UserActivityWork具有Activity id的键和用户的UserActivityWork的值。这样可以 我,但我不知道该怎么做 这在django的模板系统中(即,你怎么说:{{user_work [activity.id]}})
  • 创建一个可以容纳的对象 活动和 UserActivityWork。我没有这样做 一,因为我希望django 有一个更好的方法来做到这一点。

非常感谢任何见解!

2 个答案:

答案 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 ''