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

发布于 2024-12-08 15:37:02 字数 946 浏览 1 评论 0原文

考虑这个模型

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',),)

,我有一个显示练习的模板。

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

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

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

Consider this model

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',),)

I have a template which displays the Exercises.

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

Here is the view

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

Now I'd like to display the Score of the current user in front of each Exercise (if there is one) in order to access it from the template in this manner:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

少女净妖师 2024-12-15 15:37:02

我要做的就是预先获取所有用户当前的分数,创建一个将练习映射到分数的字典,然后将分数添加为每个练习的属性。类似于:

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 属性,它是当前用户该练习的分数(或无)。

What I'd do would be to get all the user's current scores up front, create a dictionary mapping exercise to score, then add the score as an attribute of each exercise. Something like:

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)

Now each exercise in exos has a current_user_score attribute, which is the current user's score for that exercise (or None).

莳間冲淡了誓言ζ 2024-12-15 15:37:02

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

templatetags 包内名为 exercises.py 的文件中

[将包放入 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 %}

django.contrib.auth has a context processor that adds a user variable to the template context, referencing the current user. This can enable you to get all scores for the current user, then you can create a template filter that returns the score for a particular exercise.

In a file named exercises.py within a templatetags package.

[Put the package in the folder of one of your apps in INSTALLED_APPS. Remember templatetags must be a valid Python package ie. with an __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

In the template:

{% 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 %}
没有你我更好 2024-12-15 15:37:02

也许您可以向您的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

Maybe you can add an attribute to your 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文