2011-06-18 21 views
1

すべてのリソースの特定のPersonの最新の評価を取得する方法を探しています。 現在、私はRating.objects.filter(Person = person).order_by('-timestamp') のようなクエリを使用しています。unique_everseenに、リソースとユーザー属性のキーを入力してからRating.objects.filter(id__in = uniquelist)で再検索します。 djangoクエリーセット関数でこれを行うよりエレガントな方法はありますか? これは関連するモデルです。django querysetのユーザーの最新の評価

class Person(models.Model): 
    pass 

class Resource(models.Model): 
    pass 

class Rating(models.Model): 
    rating = models.IntegerField() 
    timestamp = models.DateField() 
    resource = models.ForeignKey('Resource') 
    user = models.ForeignKey('Person') 

古い評価をすべて保存しておく必要があります。他の機能では、「変化している」履歴を保存する必要があるためです。

答えて

1

あなたがここで探しているものについて100%明確ではないですが、ユーザーが評価したすべてのリソースについて最新の評価を探したいですか? unique_everseenが実際に何をしているのかについての詳細を提供できるなら、あなたが探しているものを明確にするのに役立ちます。

あなたは、むしろ資源の観点から見ることができる:(

resources = Resource.objects.filter(rating__user=person).order_by('-rating__timestamp') 
resource_rating = [(resource, resource.rating_set.filter(person=person).get_latest('timestamp')) for resource in resources] 

あなたはSQL要求を制限するために、リソースごとの最新のレコード、またはQ objectのいくつかの巧妙な使用に到達するためにAggregate functionsを使用することができるかもしれません私の例では、いくつかのリクエストを節約でき、より洗練されているかもしれませんが、生のSQLリクエストで生成できるほどシンプルではありません。未処理のSQLでは、SELECTの内部またはGROUP BYを使用して最新の評価を取得するので、理想的なものになります。

あなたの評価モデルにpost_save signal hookと 'active'または 'current'ブール値フィールドを作成して、ユーザー/リソースと一致する他の評価を繰り返し、 'アクティブ'フィールドをFalseに設定することもできます。あなたは、その後のための単純なクエリを行うことができ

if instance.active: 
    for rating in Rating.objects.filter(user=instance.user,resource=instance.resource).exclude(id=instance.id): 
     rating.active=False 
     rating.save() 

Rating.objects.filter(user=person,active=True).order_by('-timestamp') 

これは、最も経済的だろうつまりpost_saveフックのようなものを使用して、ユーザー/リソースのために非アクティブとして、他の全ての評価をマークしますクエリ(たとえ複雑なグループを/ inner selectで作成したとしても、必要以上に複雑なクエリを処理しています)。ブール値フィールドを使用することは、ユーザーの評価が適切である場合には、「ステップ・フォワード/ステップ・バックワード」/「アンドゥ/リドゥ」の動作を提供できることを意味します。

+0

「unique_everseen」は、ここからのレシピだけです:http://docs.python.org/py3k/library/itertools.htm各項目を1回だけ生成します....この場合、最新の評価を得る。私は「アクティブ」というアイディアが好きです。 – JudoWill

+0

別のオプションは、SQLクエリを使用して[ビュー](http://dev.mysql.com/doc/refman/5.0/en/create-view.html)を設定し、関連する列を出力し、このビューをそれがDjangoのテーブルであった場合は、これを読んで使用するだけです。これにはカスタムSQLがインストールされている必要がありますが、この種の問題のためには便利なトリックです(過去には、実行時にVIEWがより高速になることが以前からわかっていました。 – Darb