Django - 从当前用户的视图中准备对象

时间:2011-10-07 08:57:33

标签: python django django-views

考虑这个模型

class Exercise(models.Model):
  name = models.CharField(max_length=50)
  def __unicode__(self):
    return self.name

class Score(models.Model):
  """Scores of users by exercise"""
  exo = models.ForeignKey(Exercise)
  user = models.ForeignKey(User)
  score = models.IntegerField()
  class Meta:
    unique_together = (('exo', 'user',),)

我有一个显示Exercise s。

的模板
<ul>
  {% for exo in exos %}
    <li>{{ exo }}</li>
  {% endfor %}
</ul>

这是视图

def view_exos(request):
  """Lists Exercises"""
  objs = {
    'exos': Exercise.objects.all(),
  }
  return render_to_response('content/contents.html', objs
  , context_instance=RequestContext(request)
  )

现在我想在每个Score(如果有的话)前面显示当前用户的Exercise,以便以这种方式从模板访问它:

<li>{{ exo }} - {{ exo.user_score }}</li>

3 个答案:

答案 0 :(得分:1)

我要做的是先获取所有用户的当前分数,创建字典映射练习进行评分,然后将分数添加为每个练习的属性。类似的东西:

user_scores = request.user.score_set.all()
score_dict = dict((sc.exo_id, sc.score) for sc in user_scores)
exos = Exercise.objects.all()
for ex in exos:
    ex.current_user_score = score_dict.get(ex.id)

现在exos中的每个练习都有current_user_score属性,这是当前用户对该练习的分数(或无)。

答案 1 :(得分:1)

django.contrib.auth有一个context processor,它将user变量添加到模板上下文中,引用当前用户。这可以让您获得当前用户的所有分数,然后您可以创建一个模板过滤器,返回特定练习的分数。

exercises.py中名为templatetags的文件中。

[将该包放在INSTALLED_APPS中的某个应用的文件夹中。请记住templatetags必须是有效的Python包,即。使用__init__.py]

from django.template import Library
register = Library()

@register.filter
def score_for_exercise(scores, exercise):
    s = scores.filter(exo=exercise)
    if s:
        return s[0].score
    return None

在模板中:

{% load exercises %}
{% with user.score_set.all as user_scores %}
<ul>
  {% for exo in exos %}
    {% with user_scores|score_for_exercise:exo as score %}
    <li>{{ exo }}{% if score %} - {{score}}{% endif %}</li>
    {% endwith %}
  {% endfor %}
</ul>
{% endwith %}

答案 2 :(得分:0)

也许您可以为Exercise添加属性:

class Exercise(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

    def user_score(self):
        return Score.objects.get(exo=self).score