Как отобразить динамические данные Django из представлений в HTML? - PullRequest
0 голосов
/ 15 октября 2019

Это кажется простой проблемой, но я просто не могу понять это правильно.

У меня есть три модели django: ProjectName, ProjectBudget и ProjectActualCost.

ProjectName хранит имя проекта (т.е. Project X).
ProjectBudget хранит имя_проекта (в виде внешнего ключа (FK)), имя_бюджета, итоговый_бюджет и дату для каждого бюджета. т.е. (проект X, гостиница, 600), (проект X, аренда, 500). «600» означает 600 долларов США. ProjectActualCost сохраняет каждую стоимость по мере ее возникновения (детализированные расходы) (т. Е. Гостиница: 100, аренда: 50, еда: 100) и ее дату. Таким образом, он хранит «имя_проекта» (как FK), «имя_бюджета» (как FK), фактическое_использование и дату. т.е. (Проект X, Гостиница, 100,10 / 03/2019), (Проект X, Гостиница, 100,10 / 06/2019), (Проект X, Аренда, 50,04 / 10/2019)

Я пытаюсь отобразить «Имя проекта», «Бюджет» и «Фактическая стоимость» в HTML-таблице. «Имя проекта» и «Бюджет» отображаются правильно, но «Фактическая стоимость» отображает только одну сумму для всей статьи затрат.

Модели:

class ProjectName(models.Model):
   project_name = models.CharField('Name',max_length = 15,blank = False)

  def __str__(self):
    return self.project_name 

class ProjectBudget(models.Model):
   project_name = models.ForeignKey(ProjectName,on_delete = models.CASCADE, 
          null = True)
   budget_name = models.CharField('Budget Name'max_length = 50
   total_budget =  models.DecimalField('Total Budget',max_digits = 9,decimal_places=2)

   def __str__(self):
    return self.budget_name 

class ProjectActualCost(models.Model):
   project_name = models.ForeignKey(ProjectName,on_delete = models.CASCADE, null = True)
   cost_description = models.ForeignKey(ProjectBudget,on_delete = models.CASCADE,null=True)
   actual_used = models.DecimalField('Actual Used',max_digits = 15,decimal_places = 2)

Просмотры:

def budgetview(request,project_id):
    budget_items = ProjectBudget.objects.filter(project_name_id =project_id)

    for budget in budget_items:
         budget_id = budget.id
         actual_cost = 
ProjectActualCost.objects.filter(cost_description_id= 
budget_id).aggregate(Sum('actual_used')).get('actual_used__sum') or 0

         print(budget.cost_description,":",actual_cost)#To test the output on StatReloader

    budget_template = "budget_view.html"

    context = {"budget_items":budget_items ,"actual_cost":actual_cost}

    return render(request,budget_template,context)

budget_view.html:

<table>
 <thead>
   <tr>
   <th>Project Name</th>
   <th>Budget Name</th>
   <th>Total Budget</th>
   <th>Total Used</th>
   </tr>

 <tbody>
    {% for item in budget_items%}
   <tr> 
        <td>{{item.project_name}}</td>
        <td>{{item.cost_description}}</td>
        <td>{{item.total_budget}}</td>
        <td>{{actual_cost}}</td>
   </tr>
   {%endfor%}

 </tbody>
 </table>

Я ожидаю увидеть:

Project Name|Budget Name | Total Budget| Total Used
 Project X     Hotel        600            200
 Project X     Rental       500            50

StratReloader отображает:

Hotel:200
Rental:50

Но когда я рендерим budget_view.html, я получаю:

 Project Name|Budget Name | Total Budget| Total Used
 Project X   |  Hotel     |   600       |    50
 Project X   |  Rental    |   500       |    50          

Я думаю, что проблема в том, что budget_id не является динамическим, когда цикл for выполняется в html.

1 Ответ

0 голосов
/ 15 октября 2019

У вас есть только одна переменная actual_cost, которую вы многократно перезаписываете на протяжении всего цикла.

Но вы не хотите использовать цикл и не хотите использовать aggregate,Вы хотите использовать annotate, который запрашивает у базы данных совокупное значение сразу для каждого элемента в наборе запросов.

budget_items = ProjectBudget.objects.filter(project_name_id=project_id).annotate(
     actual_cost=Sum('projectactualcost__actual_used')
)
budget_template = "budget_view.html"
context = {"budget_items": budget_items}
return render(request, budget_template, context)

и в шаблоне:

{% for item in budget_items %}
<tr> 
    <td>{{ item.project_name }}</td>
    <td>{{ item.cost_description }}</td>
    <td>{{ item.total_budget }}</td>
    <td>{{ item.actual_cost }}</td>
</tr>
{% endfor %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...