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信号,在评分保存后自动触发平均值更新:
- 在
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()
- 在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
相关产品推荐
相关产品推荐

