如何在Django中显示并保留每个用例的最新进度记录
解决Django中每个用例仅显示最新进度记录的问题
步骤1:确保模型关系正确
首先检查你的UsecaseProgress模型,它需要包含指向Usecase的外键(从视图代码看,关系的related_name是usecaseids)。如果模型中缺少这个字段,添加它:
class UsecaseProgress(models.Model): usecase_progress_date = models.DateTimeField(primary_key=True) usecase_progress_value = models.IntegerField() estimated_date_delivery = models.DateField(db_column='Estimated_Date_Delivery') # 添加外键关联Usecase,related_name与视图中的一致 usecase = models.ForeignKey(Usecase, models.DO_NOTHING, related_name='usecaseids') class Meta: managed = False db_table = 'usecase_progress' # 确保表名与数据库一致
步骤2:修改视图获取最新进度
方法一:简单排序取第一条(适合初学者)
通过Prefetch对象预取进度记录时,按日期倒序排列,然后在模板中取第一条即可:
from django.db.models import Prefetch def view_usecase(request): # 预取按日期倒序的进度记录,并存储到sorted_progress属性 usecase_details = Usecase.objects.prefetch_related( Prefetch( 'usecaseids', queryset=UsecaseProgress.objects.order_by('-usecase_progress_date'), to_attr='sorted_progress' ) ) context = {'usecase_details': usecase_details} return render(request, 'ViewUsecase.html', context)
方法二:子查询过滤最新记录(更高效)
如果进度记录数量较多,用子查询直接过滤出每个用例的最新记录,避免预取所有历史数据:
from django.db.models import Subquery, OuterRef def view_usecase(request): # 子查询获取每个用例的最新进度记录 latest_progress_subquery = UsecaseProgress.objects.filter( usecase=OuterRef('pk') ).order_by('-usecase_progress_date')[:1] # 给每个用例添加latest_progress注解 usecase_details = Usecase.objects.annotate( latest_progress=Subquery(latest_progress_subquery) ) context = {'usecase_details': usecase_details} return render(request, 'ViewUsecase.html', context)
步骤3:修改模板显示最新进度
移除原来遍历所有进度记录的循环,改为直接显示最新的那一条:
{% extends 'EmpDashboard.html' %} {% block body %} <div class="row d-flex"> <div class="col-12 mb-4"> <div class="card border-light shadow-sm components-section d-flex"> <div class="card-body d-flex row col-12"> <div class="row mb-4"> <div class="col-lg-12 col-sm-16"> <h3 class="h3 mb-4">View Usecases:</h3> </div> {% if usecase_details is not none and usecase_details %} <div class="table-responsive"> <table id="example" class="table table-flush text-wrap table-sm" cellspacing="0" width="100%"> <thead class="thead-light"> <tr> <th scope="col">No.</th> <th scope="col">Usecase ID</th> <th scope="col">Usecase Name</th> <th scope="col">Client</th> <th scope="col">KPI</th> <th scope="col">Progress</th> <th scope="col">Progress date</th> <th scope="col">Pipeline</th> <th scope="col">View</th> </tr> </thead> <tbody> {% for result in usecase_details %} <tr> <td>{{ forloop.counter }}</td> <td><span class="badge bg-info">{{result.usecase_id}}</span></td> <td>{{result.usecase_name}}</td> <td>{{result.business_owner.business_owner_name}}</td> <td>{{result.kpi.kpi_name}}</td> {# 根据不同的视图方法选择对应的变量 #} {% comment %} 方法一使用sorted_progress.0 {% endcomment %} {% with latest_progress=result.sorted_progress.0 %} {% comment %} 方法二使用latest_progress {% endcomment %} {% comment %} {% with latest_progress=result.latest_progress %} {% endcomment %} {% if latest_progress %} <td><div class="progress-wrapper"> <div class="progress-info"> <div class="progress-percentage"> <span>{{latest_progress.usecase_progress_value}}%</span> </div> </div> <div class="progress"> <div class="progress-bar bg-success" role="progressbar" style="width: {{latest_progress.usecase_progress_value}}%;" aria-valuenow="{{latest_progress.usecase_progress_value}}" aria-valuemin="0" aria-valuemax="100"></div> </div> </div> </td> <td>{{latest_progress.usecase_progress_date}}</td> <td>{{latest_progress.pipeline.pipeline_name}}</td> {% else %} <td>No progress recorded</td> <td>-</td> <td>-</td> {% endif %} {% endwith %} <td> <a href="/view-usecase/{{result.usecase_id}}" class="btn btn-success">VIEW</a> </td> </tr> {% endfor %} </tbody> </table> </div> {% else %} <div class="col-lg-12 col-sm-16"> <h3 class="h3 text-center"> No Records Found! </h3> </div> {% endif %} </div> </div> </div> </div> </div> {% endblock %}
注意:模板中要根据你选择的视图方法,注释掉对应的with语句。另外,进度条的宽度已经改为使用实际的进度值,替代原来的硬编码60%。
内容的提问来源于stack exchange,提问作者JHS99
相关产品推荐
相关产品推荐

