Django - подготовить объекты из представления для текущего пользователя - PullRequest
1 голос
/ 07 октября 2011

Рассмотрим эту модель

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 ]

1 голос
/ 07 октября 2011

Что бы я сделал, чтобы получить все текущие оценки пользователя заранее, создать словарное упражнение для сопоставления, а затем добавить счет в качестве атрибута каждого упражнения. Что-то вроде:

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 голос
/ 07 октября 2011

django.contrib.auth имеет процессор контекста , который добавляет переменную 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 %}
0 голосов
/ 07 октября 2011

Может быть, вы можете добавить атрибут к вашему 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
...