3

Django (ドイツ語-スウェーデン語) を使用して語彙トレーニング プログラムを開発しています。

アプリの語彙データは多数の「語彙カード」で構成されており、各カードには、1 つまたは複数のスウェーデン語の用語に対応する 1 つまたは複数のドイツ語の単語または用語が含まれています。

scoreアプリは語彙カードごとに保存することでユーザーのパフォーマンスを追跡するため、トレーニングは登録ユーザーのみが利用できます。

語彙カードには、レベル (基本、上級、エキスパート) と任意の数のタグが割り当てられています。

登録ユーザーがトレーニングを開始すると、ユーザーが選択できるように、アプリケーションはレベルとタグごとにユーザーの平均スコアを計算する必要があります。

この問題は、 and フィールドとモデルとの関係をCardByUser持つという名前のモデルを導入することで解決しました。これで、Django の集計関数を使用して平均スコアを計算できるようになりました。scoreForeignKeyUserCard

大きな欠点: これはCardByUser、ユーザーが 100 枚のカードしかトレーニングしていない場合でも、現在 DB に存在するすべての Card インスタンスのインスタンスがある場合にのみ機能します。私の現在の解決策は、作成時とユーザーの登録時にこれらすべてのCardByUserインスタンスを作成することです。Cardもちろん、これはデータベース メモリと計算時間の両方の点でかなり非効率的です (ユーザーの登録にはかなりの時間がかかります)。

そして、それは非常に洗練されていないように思えます。それが私を最も悩ませています。

これを行うより良い方法はありますか?

の平均スコアを計算するときに、Django に次のように伝えることができるかもしれませんCard

  • CardByUser指定されたユーザーが存在する場合Cardは、そのスコアを使用します。
  • CardByUserが存在しない場合は、デフォルト値 --> スコア 0 を使用します。

これはできますか?もしそうなら、どのように?

編集:明確化 最初の回答をありがとうS.Lott'sですが、私の問題はもう少し複雑だと思います。残念ながら、モデルの実際のコードを使用して明確にしようとしています。

class Card(models.Model):
    entry_sv = models.CharField(max_length=200)
    entry_de = models.CharField(max_length=200)
    ... more fields ...

class CardByUser(models.Model):
    user = models.ForeignKey(User)
    card = models.ForeignKey(Card, related_name="user_cards")
    score = models.IntegerField(default=0)
    ... more fields ...

これは、多くのCardByUserオブジェクトが 1 つの に関連付けられていることを意味しますCard

ビュー コードではCardByUser、次の基準を満たすオブジェクトのクエリセットを作成する必要があります。

  • 関連するCardオブジェクトのtagフィールドには特定の文字列が含まれています(これも最適ではありませんが、私の質問の焦点では​​ありません...)
  • ユーザーは現在のユーザーです

次に、スコアを集計できます。私の現在のコードは次のようになります(短縮):

user_cards = CardByUser.objects.filter(user=current_user)
                               .filter(card__tags__contains=tag.name)
avg = user_cards_agg.aggregate(Avg('score'))['score__avg']

CardByUser現在のユーザーのCardが存在しない場合は、単に集計に含まれません。そのため、これらすべてのCardByUsers をスコア 0 で作成します。

では、どうすればそれらを取り除くことができますか?どんなアイデアでも大歓迎です!

4

2 に答える 2

2

これが、メソッド (およびおそらくプロパティ) の目的です。

class OptionalFKWithDefault( models.Model ):
    another = models.ForeignKey( AnotherModel, blank=True, null=True )
    @property
    def another_score( self ):
        if self.another is None:
            return 0
        else:
            return self.another.score
于 2009-06-05T15:32:12.490 に答える
1

これはあなたの質問に完全に関連しているわけではないかもしれませんが、CardByUser実際には余分なフィールドとの多対多の関係であるように見えます. ( http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationshipsを参照)

このようにモデルを変更できますか?

class Card(models.Model):
    entry_sv = models.CharField(max_length=200)
    entry_de = models.CharField(max_length=200)
    ... more fields ...
    users = models.ManyToManyField(User, through='CardByUser')

class CardByUser(models.Model):
    user = models.ForeignKey(User)
    card = models.ForeignKey(Card)
    score = models.IntegerField(default=0)

これはすべて Django によって処理されるため、明示的に CardByUser オブジェクトを作成する必要はありません。集計クエリも簡素化できるはずです。

user_cards = Card.objects.filter(users=current_user)
                         .filter(tags__contains=tag.name)
...
于 2009-06-08T11:08:48.587 に答える