Django中如何在所有推荐人审批通过后展示指定数据
实现方案:仅当所有推荐人批准后展示审批主题和附件
注意:你的三个模型中都定义了
objects = None,这会覆盖Django默认的模型管理器,导致无法执行ORM查询,必须删除这一行代码。
以下是三种可行的实现方案,可根据业务场景选择:
方案一:ORM聚合查询直接筛选符合条件的记录
通过Django聚合函数,直接从数据库层面筛选出所有关联推荐人全为"Approved"状态的SendApproval实例:
from django.db.models import Count, Q, F # 获取符合条件的审批记录 qualified_approvals = SendApproval.objects.annotate( total_recommenders=Count('recommenders'), approved_recommenders=Count('recommenders', filter=Q(recommenders__Status='Approved')) ).filter( total_recommenders__gt=0, # 确保存在推荐人记录(可根据需求移除) total_recommenders=F('approved_recommenders') )
- 逻辑说明:
annotate为每个SendApproval添加两个统计字段——所有推荐人数量、已批准的推荐人数量,通过filter判断两者相等,即可确认该主题下所有推荐人已批准。 - 若业务允许无推荐人记录的审批也展示,删除
total_recommenders__gt=0条件即可。
方案二:给模型添加属性方法做判断
在SendApproval模型中添加一个属性方法,用于判断当前主题是否满足所有推荐人已批准的条件:
class SendApproval(models.Model): Subject = models.CharField(max_length=256) Date = models.DateField(null=True) Attachment = models.FileField(upload_to=get_file_path) SentBy = models.CharField(null=True, max_length=100) Status = models.CharField(null=True, max_length=8, default="Pending") @property def all_recommenders_approved(self): recommenders = self.recommenders.all() # 无推荐人时可根据需求返回True/False if not recommenders: return False # 检查所有推荐人状态是否为Approved return all(rec.Status == 'Approved' for rec in recommenders)
视图与模板配合
视图中获取所有审批记录:
def approval_list(request): # 预加载推荐人数据避免N+1查询 all_approvals = SendApproval.objects.all().prefetch_related('recommenders') return render(request, 'approval_list.html', {'approvals': all_approvals})
模板中通过属性判断是否展示字段:
{% for approval in approvals %} {% if approval.all_recommenders_approved %} <div class="approval-item"> <h3>主题:{{ approval.Subject }}</h3> <p>附件:<a href="{{ approval.Attachment.url }}" target="_blank">下载文件</a></p> </div> {% endif %} {% endfor %}
方案三:用信号自动更新审批状态
如果需要频繁判断审批状态,可通过Django信号在推荐人状态变更时,自动更新SendApproval的状态字段,后续直接通过状态筛选即可:
1. 定义信号处理函数
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=Recommenders) def sync_approval_status(sender, instance, **kwargs): send_approval = instance.Subject if not send_approval: return total_recs = send_approval.recommenders.count() approved_recs = send_approval.recommenders.filter(Status='Approved').count() if total_recs > 0 and total_recs == approved_recs: send_approval.Status = 'Approved' else: send_approval.Status = 'Pending' send_approval.save()
2. 注册信号
在apps.py中添加信号注册逻辑:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app_name.signals # 导入信号模块
3. 查询使用
之后直接通过状态筛选符合条件的审批记录:
qualified_approvals = SendApproval.objects.filter(Status='Approved')
- 优势:避免重复计算,性能更优,适合高并发或数据量较大的场景。
内容的提问来源于stack exchange,提问作者LAVANYA GANESH TADAVARTI
相关产品推荐
相关产品推荐

