从django模板中的外键关系中获取过滤的对象

时间:2013-07-04 20:42:29

标签: django

我遇到问题djangos design choice不允许在模板中进行模型过滤。实际上,我确实理解它的意义,我真的不想打破它,但目前我看不出用什么方法来规避我的情况。

我的模型Task带有外键user_solutions到另一个模型Solution。现在我正在迭代所有任务,如果用户已经有了这个任务的解决方案,我想显示勾选和他的解决方案的链接。有点像这样:

{% for task in tasks %}
    {{ task.title }}
    {% if task.user_solutions.filter(author=author).count() > 0 %}
        Tick!
        {{ task.user_solutions.get(author=author).get_absolute_url }}
    {% endif %}
{% endfor %}

是的,对于相同的信息,它看起来很残酷地查询数据库两次,并且django模板不会像这样(正确地)接受它。

然而,其他方法似乎也不起作用:

  • 我无法添加方法Task.get_current_user_solution(),因为在模型中我不知道登录了哪个用户
  • 我无法添加方法Task.get_user_solution(user),因为我无法通过模板传递参数
  • 我无法在视图中查询信息并将其保存到字典current_users_solutions(以Task.id作为索引),因为在模板中,我无法使用组合变量来访问字典(以及索引到访问它当然是task.id

那我还能做什么呢?从链接的文章我只能看到我可以添加一个新的模板标签以允许从模板查询,但正如所说,我实际上想跟随djangos设计原则,如果可能。

3 个答案:

答案 0 :(得分:2)

Django执行此操作的方法是创建一个自定义模板标记,该标记接受用户参数并适当地过滤查询集。这只是几行代码。

Django对于“模板中没有逻辑”并不是教条主义(一般来说,教条主义在皱眉中是不受欢迎的,也就是说“实用性胜过纯洁”)。它没有提供在模板语言中本机执行此类操作的能力,但这就是为什么它根本就有自定义模板标签:如果您的设计需要它,最简单的方法是从模板查询那就是你应该做的。

答案 1 :(得分:1)

您可以在视图中添加任意内容,因此,在views.py中,您可以执行以下操作:

# in views.py
for task in tasks:
    if task.user_solutions.filter(author=author).count() > 0:
        task.is_this_users = True
        task.url = task.user_solutions.get(author=author).get.absolute_url

然后在你的模板中:

{% for task in tasks %}
    {{ task.title }}
    {% if task.is_this_users %}
        Tick!
        {{ task.url }}
    {% endif %}
{% endfor %}

答案 2 :(得分:0)

  

你可以像这样使用django模板标签:   templatetags.py   @ register.inclusion_tag( “template.html”)   def task_def(请求):   task = user_solutions.filter(author = author).count()   如果任务> 0:   task.is_this_users = True   task_url = task.user_solutions.get(author = author).get.absolute_url   return {'task_url':task_url}

     模板文件中的

(.html)   {%load templatetags%}   现在你可以在这里使用你想要的返回结果了   {%for task_url%}}