You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django:提交新评分后更新数据库中的企业平均评分

问题描述

我有一个展示企业信息的表格,其中models.FicheIdentification表的note_moyenne字段用于存储企业收到的评分平均值。用户点击按钮提交新评分时(对应models.EvaluationGenerale表的note字段),希望数据库中的平均值能自动更新。

目前我通过实时计算展示平均值:

def render_evaluation(self, record):
    return (EvaluationGenerale.objects.filter(entreprise=record.entreprise.siret).aggregate(Avg('note'))['note__avg'])

但我想把这个值存储到数据库的FicheIdentification.note_moyenne字段中。尝试过创建UpdateView类,但无法与现有的CreerEvaluationGenerale(CreateView)关联,求解决方法或思路。

相关代码

models.py

class FicheIdentification(models.Model):
    entreprise=models.ForeignKey(Entreprise, on_delete=models.CASCADE)
    note_moyenne=models.IntegerField()

    def __str__(self):
        return self.entreprise.nom_entreprise

class EvaluationGenerale(models.Model):
    entreprise=models.ForeignKey(Entreprise, on_delete=models.CASCADE)
    note=models.IntegerField()
    commentaires=models.CharField(max_length=1000)
    date_evaluation=models.DateField(auto_now_add=True)

    def __str__(self):
        return self.commentaires

views.py

class CreerEvaluationGenerale(CreateView):
    form_class = FormulaireEvaluationGenerale
    model = EvaluationGenerale
    def form_valid(self, form):
        form.instance.entreprise=Entreprise.objects.filter(siret=self.kwargs['siret']).first()
        return super(CreerEvaluationGenerale, self).form_valid(form)
    def get_success_url(self):
        return reverse('details-evaluations')
解决方案

方法一:在CreateView的form_valid中直接更新平均值

无需单独创建UpdateView,直接在提交评分的form_valid方法中新增计算并更新平均值的逻辑:

from django.db.models import Avg

class CreerEvaluationGenerale(CreateView):
    form_class = FormulaireEvaluationGenerale
    model = EvaluationGenerale
    
    def form_valid(self, form):
        # 关联企业并保存新评分
        form.instance.entreprise = Entreprise.objects.filter(siret=self.kwargs['siret']).first()
        response = super().form_valid(form)
        
        # 计算当前企业的平均评分
        entreprise = form.instance.entreprise
        avg_note = EvaluationGenerale.objects.filter(entreprise=entreprise).aggregate(Avg('note'))['note__avg']
        
        # 更新对应FicheIdentification的平均值字段
        # 假设每个企业对应唯一的FicheIdentification记录
        fiche = FicheIdentification.objects.get(entreprise=entreprise)
        # 处理无评分时的空值情况,默认设为0
        fiche.note_moyenne = int(avg_note) if avg_note is not None else 0
        fiche.save()
        
        return response
    
    def get_success_url(self):
        return reverse('details-evaluations')

方法二:使用Django信号自动更新(解耦业务逻辑)

如果不想在视图中嵌入业务逻辑,可以用Django的post_save信号,在评分保存后自动触发平均值更新:

  1. 在models.py中添加信号处理函数:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db.models import Avg

@receiver(post_save, sender=EvaluationGenerale)
def update_note_moyenne(sender, instance, created, **kwargs):
    # 无论新增还是修改评分,都更新平均值
    entreprise = instance.entreprise
    avg_note = EvaluationGenerale.objects.filter(entreprise=entreprise).aggregate(Avg('note'))['note__avg']
    fiche = FicheIdentification.objects.get(entreprise=entreprise)
    fiche.note_moyenne = int(avg_note) if avg_note is not None else 0
    fiche.save()
  1. 在app的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.models  # 确保信号被导入加载

内容的提问来源于stack exchange,提问作者LadyNaur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:25:41