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

これらの結果を「メモ化」したい場合は、たどることができるパスが少なくとも2つあります。

  1. メトリックテーブルの「members_count」、「members_total」、および「members_max」フィールドを更新する、Membersテーブルの行ごとの保存後トリガー。

    これに伴う課題は、トリガー作成DDLを残りのコードと一緒に維持し、モデルが再作成または変更されるたびに自動的に適用することです。

    Django ORMは、これを特に簡単にするものではありません。最も一般的な移行ツール(南)も、これを簡単にするために邪魔になりません。また、このソリューションは1つのRDBMSに固有であり、一部のRDBMSはこれをサポートしていない可能性があることにも注意してください。

  2. メトリックモデルに「合成」フィールドを作成し、保存後の信号ハンドラーを使用して、メンバーが追加または変更されるたびにそれらを更新できます。

    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で文書化]たとえば、メトリックの「me」インスタンスがあると仮定します。

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

これらの集約があまり頻繁に使用されない場合、パス#2は実行可能でより保守しやすいオプションになる可能性があります。

于 2012-10-12T07:12:02.917 に答える