django:管理要在模板上显示的数据

时间:2012-03-14 19:19:09

标签: django reporting django-queryset

有没有办法以某种方式预先选择查询集中的数据,然后再转到模板?这个'项目'模型连接到'project_phase',并且有'project_phase_history'记录可以跟踪所有状态变化。

我正在这些数据之上构建报告,并在一个页面上显示所有项目,并且只想显示过去几天或最近一次提交的project_phase_history。

我尝试在视图中这样做:

projects_to_report_on = project.objects.filter(Q(current_phase__phase__id__in=[1,2,3,4]) & Q(role_sponsor__id = sponsor_id))
projects_to_report_on.current_phase.project_phase_history_set = projects_to_report_on.current_phase.project_phase_history.filter(...)

但是这没有用,实际上 - 所有数据似乎都跳进了模板。

我最终将日期传递给模板并生成报告,如下所示:

{% for s in p.current_phase.project_phase_history_set.all %}
    {% if s.date_submitted >= status_start_date %}

    <tr>
    <td>{{ s.date_submitted }}</td>
    <td>{{ s.date_end_fact|default_if_none:"-" }}</td>
  </tr>
      {% endif %}
      {% endfor %}

但它没有我想要的灵活性。

class project(models.Model):
    name = models.CharField(max_length=100, null=False, unique=True)
    description = models.CharField(max_length=1024,null=True,blank=True)
    current_phase = models.ForeignKey('project_phase', null=True, blank=True, related_name="current_phase")

class project_phase(models.Model):
    phase = models.ForeignKey('phases')
    project = models.ForeignKey('project')
    is_finished = models.BooleanField(default=False)

class project_phase_history(models.Model):
    project_phase = models.ForeignKey('project_phase')
    date_start_plan = models.DateField(null=True, blank=False)
    date_start_fact = models.DateField(null=True, blank=True)

1 个答案:

答案 0 :(得分:0)

这是你的问题:

projects_to_report_on.current_phase.project_phase_history_set = projects_to_report_on.current_phase.project_phase_history.filter(...)

您正在将关系反向的Manager设置为QuerySet。这不起作用。以下是博客和条目模型的示例:

>>> print(Entry.objects.all())
[<Entry: Today>, <Entry: Hello>]
>>> today = datetime.date.today()
>>> print(Entry.objects.filter(pub_date__lt=today).all())
[<Entry: Hello>]
>>> blog.entry_set = Entry.objects.filter(pub_date__lt=today())
>>> print(blog.entry_set.all())
[<Entry: Today>, <Entry: Hello>]
>>> blog.entry_set = Entry.objects.none()
>>> print(blog.entry_set.all())
[<Entry: Today>, <Entry: Hello>]

由于:

>>> blog.entry_set = Entry.objects.all()
>>> type(blog.entry_set)
<class 'django.db.models.fields.related.RelatedManager'>

这意味着blog.entry_set仍然是管理员,在管理器上调用all只会返回所有记录。所以不要这样做。将QuerySet传递给您的模板并使用:

history_set = projects_to_report_on.current_phase.project_phase_history_set.filter(...)
# add it to the context as 'history_set'

{% for s in history_set.all %}

由于您需要遍历项目和该项目的历史记录,我会将字典传递给模板:

from django.utils.datastructures import SortedDict
# ...
project_map = SortedDict()
for project in projects_to_report_on:
    project_map[project] = history_query_set_goes_here
# ...
return render(request, template, {'project_map': project_map})

然后在你的模板中:

{% for project, history_set in project_map.items %}
    <h2>{{ project }}</h2>
    <ol>
    {% for history in history_set.all %}
        <li>{{ history }}</li>
    {% endfor %}
    </ol>
{% endfor %}

SortedDict is documented on the Django wiki。它维护插入顺序,因此如果您以正确的顺序从数据库中检索项目,它们将以相同的顺序显示。