0

这是我的模型文件的一部分:

class Metric(models.Model):
    Team = models.ForeignKey(Team)
    metric_name = models.CharField(max_length = 40)
    def __unicode__(self):
            return self.metric_name


class Members(models.Model):
    Metric = models.ForeignKey(Metric, through="Calculate")
    member_name = models.CharField(max_length = 40, null=True, blank=True)
    week_one = models.IntegerField(null=True, blank=True)
    week_two = models.IntegerField(null=True, blank=True)
    week_three = models.IntegerField(null=True, blank=True)
    week_four = models.IntegerField(null=True, blank=True)
    total = models.IntegerField(null=True, blank=True)
    def __unicode__(self):
            return self.member_ID

    def save(self, *args, **kwargs):
            self.total = int(self.week_one)+int(self.week_two)+int(self.week_three)+int(self.week_four)
            super(Members, self).save(*args, **kwargs) # Call the "real" save() method.

现在我想做的是。我想计算每个指标的成员数、指标中所有成员的总和以及指标中所有成员中的最高总数。

我想不出在 Django 中执行此操作的方法。我想进行这些计算并将它们存储在数据库中。谁能帮我解决这个问题。谢谢

4

1 回答 1

0

如果您希望“记忆”这些结果,至少可以遵循两条路径:

  1. 成员表上的每行保存后触发器,用于更新 Metric 表中的“members_count”、“members_total”和“members_max”字段。

    这样做的挑战在于,将触发器创建 DDL 与其余代码一起维护,并在重新创建或更改模型时自动应用它。

    Django ORM 并没有让这变得特别容易。最常见的迁移工具 ( south ) 也没有竭尽全力使这变得容易。另请注意,此解决方案将特定于一个 RDBMS,并且某些 RDBMS 可能不支持这一点。

  2. 您可以在 Metric 模型中创建“合成”字段,然后在添加或更改成员时使用保存后信号处理程序更新它们。

    class Metric(models.Model):
        Team = models.ForeignKey(Team)
        metric_name = models.CharField(max_length = 40)
    
        members_count = models.IntegerField()
        members_max = models.IntegerField()
        members_total = models.IntegerField()
    
        def __unicode__(self):
            return self.metric_name
    
    # signal handling
    from django.db.models import signals
    from django.dispatch import dispatcher
    
    def members_post_save(sender, instance, signal, *args, **kwargs):
        # Update the count, max, total fields
        met = sender.Metric # sender is an instance of Members
        metric.members_count = Members.objects.filter(Metric=met).count()
        # more code here to do the average etc;
    
    dispatcher.connect(members_post_save, signal=signals.post_save, sender=Members)
    

此处的 django 信号文档很有用。

注意事项

  1. 虽然可以采用这种方法来实现您的既定目标,但它很脆弱。您需要具有测试覆盖率,以确保此信号处理程序始终触发,即使在您对代码进行了一些重构之后也是如此。
  2. 我还会考虑使用“相关对象”查询[记录在https://docs.djangoproject.com/en/dev/topics/db/queries/#related-objects ] 例如,假设我们有一个“我”实例

    >> members_count = me.members_set.count()
    >> # aggregation queries for the total and max
    

如果这些聚合不经常使用,那么路径 #2 可能是一个可行且更易于维护的选项。

于 2012-10-12T07:12:02.917 回答