2016-04-14 4 views
2

私はいくつかのフィールドの履歴データが必要なモデルを持っているので、これらのフィールドを外部キー関係。ソートのこのような別のモデルの最新の対応するエントリのテキストフィールドを使ってDjangoクエリーセットをフィルタリングする方法

何か:

class DataThing(models.Model): 
    # a bunch of fields here... 


class DataThingHistory(models.Model): 
    datathing_id = models.ForeignKey('DataThing', on_delete=models.CASCADE) 
    text_with_history = models.CharField(max_length=500, null=True, blank=True) 
    # other similar fields... 
    timestamp = models.DateTimeField() 

は今、私は後者の最新の対応するエントリのテキストフィールドを使用して、元のモデルにフィルタを適用しようとしています。

search_results = DataThing.objects.filter(text_with_history__icontains=searchterm) 

しかし、私はこの1対多の関係を越え、これを行うための良い方法を考え出したとだけ使用していない:これらのモデルを分離していなかった場合

基本的に私はこれを試してみました後者のモデルでは、少なくともDjango ORMを使用して、最新のタイムスタンプを持つエントリを作成します。

私は未処理のSQLを使用したいクエリをどのように行うのか考えていますが、できる限りrawを使用しないようにしたいと考えています。

答えて

0

このソリューションは、現在だけではPostgresでサポートされていdistinct(*fields)を利用します。私は可読性のためにクエリを分割しましたが、あなたはそれを一つのステートメントに入れ子にすることができます。 Btw、foo_idは、ForeignKeyフィールドには適していません。

+0

これをお寄せいただきありがとうございます。私はこれを試しました。私はいくつかのテストをしなければならないし、それが実際にどのくらいうまく走るのかを見なければならないでしょうが、これは今のところ私の問題を解決するようです。 – jyap

0

DataThingHistoryを参照しながら、あなたはDataThingを照会することによって、同じことをするだろう:how to query on reverse relationship

search_results = DataThing.objects.filter(datathinghistory__text_with_history__icontains=searchterm) 

チェックDjangoのドキュメントを。

編集:

私の前の回答が不完全です。各DataThingの最新の履歴に検索するためには、Maxを使用してタイムスタンプにannotateする必要があります。

from django.db.models import Max 

search_results = search_results.values('field1', 'field2',...).annotate(latest_history=Max('datathinghistory__timestemp')) 

これは、あなたがDataThingオブジェクトを完了与えないだろうが、あなたが望むとおりにvaluesにできるだけ多くのフィールドを追加することができます。

latest_things = DataThingHistory.objects. 
    order_by('datathing_id_id', '-timestamp'). 
    distinct('datathing_id_id') 

lt_with_searchterm = DataThingHistory.objects. 
    filter(id__in=latest_things, text_with_history__icontains=searchterm) 

search_results = DataThing.objects.filter(datathinghistory__in=lt_with_searchterm) 

これは、単一のDBクエリを生じるはずである:

+0

'DataThingHistory'オブジェクトを最新の' timestamp'でチェックするにはどうすればよいですか?あなたが記述するクエリを実行するだけで、関連するすべての 'DataThingHistory'エントリが検索されるようです。 – jyap

+0

申し訳ありませんが私はあなたの要件を完全に逃した。私は自分の答えを編集して、意味があるかどうかを確認します。 –

関連する問題