django父视图中的子项求和并传递给模板

时间:2016-04-05 14:45:09

标签: python django

我是Django的新手,我希望做以下工作,我有一个简单的项目,并拥有项目和相关项目任务的父子模型。一个项目将有多个ProjectTasks。 我希望能够通过模板显示Project和ProjectTask总和。

class Project(models.Model):
    projectContact = models.ForeignKey(Contact)
    projectTitle = models.CharField(max_length=100)
    projectAddress1 = models.CharField(max_length=200)
    projectValueProposed = models.IntegerField(default=0)
    projectValueActual = models.IntegerField(default=0)
    def __str__(self):
        return self.projectTitle

class ProjectTask(models.Model):
    projectName = models.ForeignKey(Project)
    projectTaskDesc = models.CharField(max_length=200)
    projectTaskContact = models.ForeignKey(Contact)
    projectTaskAmount = models.IntegerField(default=0)
    def __str__(self):
        return self.projectTaskDesc

我的观点如下。

def index(request):
    project_list = Project.objects.all()
    project_task = ProjectTask.objects.all()
    ##project_task = ProjectTask.objects.all() ##filter(projectName=2).aggregate(amount=Sum('projectTaskAmount'))
    for pid in project_list:
        ptask = project_task.filter(projectName=pid.id)
    context = {'project_list':project_list,'project_task':ptask}
    return render(request,'construction/index.html',context)

和模板是

{% if project_list %}
<table class="tg">
  <tr>
    <th class="tg-le8v">Project name</th>
    <th class="tg-le8v">Customer</th>
    <th class="tg-le8v">Proposed Value</th>
    <th class="tg-le8v">Actual Value</th>
  </tr>

 {% for projects in project_list %}
  <tr>
    <td class="tg-yw4l"><a href="{% url 'construction:projectview' projects.id%}">{{ projects.projectTitle }}</a></td>
    <td class="tg-yw4l">{{ projects.projectContact }}</td>
    <td class="tg-yw4l">{{ projects.projectValueProposed }}xx{{projects.id }}</td>
    <td class="tg-yw4l">{{ project_task}}</td>
  </tr>
  {% endfor %}

</table>
 {% else %}
    <p>No projects are available.</p>
{% endif %}

我使用Admin创建Project并添加projectTask,效果很好。 我有两个选择: 1.在我保存管理页面时更新项目中projectValueActual的值 2.动态显示项目和相关ProjectTaskAmount的总和

需要一些关于如何在视图中准备值的帮助(如果这是正确的位置)并以某种方式传递上下文我可以显示它。

2 个答案:

答案 0 :(得分:0)

模型属性的名称可以更简洁。另外,将foreign_name添加到ForeignKey,以便您可以直接从Project模型中引用它。

class Project(models.Model):
    contact = models.ForeignKey(Contact)
    title = models.CharField(max_length=100)
    address1 = models.CharField(max_length=200)
    valueProposed = models.IntegerField(default=0)
    valueActual = models.IntegerField(default=0)

    def __str__(self):
        return self.title

class ProjectTask(models.Model):
    project = models.ForeignKey(Project, related_name='tasks')
    description = models.CharField(max_length=200)
    contact = models.ForeignKey(Contact)
    amount = models.IntegerField(default=0)

    def __str__(self):
        return self.description

这使视图更加简单

def index(request):
    ctx = {'project_list': Project.objects.all()}
    return render(request, 'construction/index.html', ctx)

我不太确定你想在模板中做什么,但我们假设你想要列出每个相关项目下的所有任务,然后打印ProjectTask.amount值的总和。

{% if project_list %}
<table class="tg">
  <tr>
    <th class="tg-le8v">Project name</th>
    <th class="tg-le8v">Customer</th>
    <th class="tg-le8v">Proposed Value</th>
    <th class="tg-le8v">Actual Value</th>
  </tr>

  {% for project in project_list %}
  <tr>
    <td class="tg-yw4l"><a href="{% url 'construction:projectview' projects.id%}">{{ project.title }}</a></td>
    <td class="tg-yw4l">{{ project.contact }}</td>
    <td class="tg-yw4l">{{ project.valueProposed }}xx{{projects.id }}</td>
    <td class="tg-yw4l">
      {% for task in project.tasks %}
        <span>{{ task.amount }}</span>
        {% if forloop.last %} = {% else %} + {% endif %}
      {% endfor %}

      {{ project.sumTaskAmounts }}
    </td>
  </tr>
  {% endfor %}

</table>
 {% else %}
    <p>No projects are available.</p>
{% endif %}

最后,要轻松获取所有Task.amount属性的总和,您需要将@property添加到Project,以返回amount值的总和每个项目的ProjectTask个实例。

class Project(models.Model):
    ...

    @property
    def sumTaskAmounts(self):
        return self.tasks.aggregate(amount=Sum('amount')).amount

没有测试任何一个,但这应该或多或少地做。

答案 1 :(得分:0)

我在保存管理表单时进行了以下更改以实施更新。

models.py

  def update_total_amount(self):
        total=0
        total=self.task.aggregate(amount=Sum('amount'))
        self.valueActual=total['amount']
        self.save()

和admin.py

def save_formset(self, request, form, formset, change):
            instances = formset.save(commit=False)
            for instance in instances:
                instance.save()
            formset.save_m2m()
            instance.project.update_total_amount()

适用于我想做的事情。谢谢你的帮助。