2

私はこれらのモデルを持っています:

class Package(models.Model):
    title = CharField(...)

class Item(models.Model)
    package = ForeignKey(Package)
    price = FloatField(...)

class UserItem(models.Model)
    user = ForeignKey(User)
    item = ForeignKey(Item)
    purchased = BooleanField()

可能な限り最高のパフォーマンスで2つの機能を達成しようとしています:

  1. 私のテンプレートでは、すべてのアイテムの各パッケージ価格の合計を計算したいと思います。(私が推測する集計?)

  2. より複雑: ユーザーごとに、購入したすべてのアイテムの価格を合計できることを望みます。購入した = True。

1つのパッケージに10個のアイテムがあり、それぞれが10ドルで、パッケージの合計は100ドルであると仮定します。ユーザーが 5 つのアイテムを購入すると仮定すると、2 番目の合計は 50 ドルになります。

テンプルタグで簡単なクエリを簡単に実行できますが、もっとうまくできると思いますか? (うまくいけば)

4

3 に答える 3

3

特定のパッケージの価格を合計するには、a_packageこのコードを使用できます

Item.objects.filter(package=a_package).aggregate(Sum('price'))

これらの種類のクエリを実行する方法に関するガイドと、説明されているすべての異なる関数を含む集約ドキュメントがあります。

この種のクエリは、2番目の問題も解決できます。

UserItem.objects.filter(user=a_user).filter(purchased=True).aggregate(sum('price'))

annotate()各オブジェクトにカウントを添付するために使用することもできます。上記の最初のリンクを参照してください。

于 2012-08-03T08:31:36.097 に答える
3

@VicSmithが解決策を得ました。

ただし、必要に応じてモデルpriceに属性を追加しますpackage

可能な限り最高のパフォーマンス

Itemにシグナルを追加し、作成された場合は、関連するオブジェクトon_saveを更新します。package

このようにして、パッケージの価格を非常にすばやく取得でき、並べ替えや比較などもすばやく行うことができます。

purchasedさらに、私は属性の目的を実際には理解していません。Itemただし、との間で多対多の関係を作成し、パラメータとの接続としてUser定義することをお勧めします。UserItemtrhough

とにかく、私の経験では、あなたは通常、直接リンクではなく、にリンクされているオブジェクトItemとの関係を作りたいと思っています(パフォーマンスの問題が発生し始めない限り...)。イベントの記録として「ユーザーがこれとあれをぶち壊す」ことで、処理が容易になります。PurchasseUserPurchasse

于 2012-08-03T08:46:18.143 に答える
3

私の意見では、最も洗練された方法は、 Model クラスでメソッドを定義し、それをプロパティtotalとして装飾することです。これは、またはのいずれかに対して(Django ORM のSum aggregateを使用して) を返します。totalPackageUser

クラスの例Package:

from django.db.models import Sum

...

class Package(models.Model):

    ...

    @property
    def total(self):
        return self.item_set.aggregate(Sum('price'))

テンプレート コードではtotal、他のモデル属性として使用します。例えば:

{{ package_instance.total }}
于 2012-08-03T08:44:11.343 に答える