2009-08-28 22 views
0

私は、好ましくは、複数のビューで使用することができ、一般的な方法で、濾過し、ソートされたオブジェクトのリストを維持する必要があります。これは必要なので、私は次のリンクを生成し、他の非常に有用なものをユーザに提供することができます。フィルタの複雑なフィルタ状態を維持するための戦略?

例:フィルタクエリセットが構築された後

field__isnull=True 
field__exact="so" 
field__field__isnull=False 

はまた、順序はフィールドのいずれかによって適用することができます。

私の現在のソリューションは、最初のクエリセットと一緒に、フィルタのコレクションを含むFilterSpecにクラスを使用することです。このクラスは次にシリアル化され、ビューに渡されます。

25の動的濾過アイテムとビューを考えます。ビューの各アイテムには、アイテムの詳細なビューを取得するためのリンクがあります。これらのリンクのそれぞれに、現在のリストの直列化されたFilterSpecオブジェクトが追加されます。だからあなたは巨大なURLで終わる。さらに悪いことに、同じ巨大なフィルタがすべての25のリンクに追加されています!

別のオプションは、セッションではFilterSpecを格納することですが、その後、あなたはFilterSpecにを削除する際の問題に実行します。次に、オブジェクトの新しいリストの準備のためにフィルタを削除する必要があるかどうかを判断しようとするコードで、すべてのビューが混乱していることがわかります。

私はこの問題は以前に解決されていると確信しているので、私はあなたたちがが出ている他のソリューションを聞いてみたいです。

答えて

2

あなたはAにユーザー固有の状態を維持するための2つのオプションが特定されましたウェブアプリケーション:クッキー/セッションに保存するか、URLに渡します。私はあなたの問題を解決するために翼の中に待っている第三の「銀の弾丸」があるとは思わない。

URLクエリー文字列オプションには、特定のビューステートをブックマークして、電子メールURLの&cとして送信できるという利点があります。また、ビューコードを少しシンプルに保つかもしれませんが、適切なクエリ文字列が常にリンク上で確実に渡されるように、いくつかの追加のテンプレートコードを犠牲にしてください。

一部の解決方法は、必要な動作によって異なる場合があります。たとえば、アイテムの詳細ビューのURLをブックマーク(または友人に電子メール)すると、そのURLを単にアイテム自体を参照するか、そのアイテムがどのリストに出てきたかに関する情報の?前者の場合は、セッションデータを使用します。後者の場合は、URLをクエリ文字列とともに使用します。

どちらの場合でも、「すべてのビューを混乱させる」というコードは、エレガントでドライで、目に見えないようにリファクタリングできると確信しています。デコレータやクラスベースのビューが役立つかもしれません。

+0

Carlさんに感謝します。はい、私はこの問題をすでに解決していたサードパーティ製の「銀色の弾丸」アプリケーションがあることを期待していました。これは臨床応用であるため、URL共有は予期されません。私はセッションがより適切だと思いますが、これを聞かせてください:詳細ビューを終了するとき、詳細ビューがリンクするすべてのビューからこのセッション変数をクリアせずにどのようにクリアしますか? – slypete

+0

@slypete申し訳ありませんが、私はあなたの質問を理解していません。セッション変数をクリアする必要があるのはなぜですか? 「詳細ビューを終了するとき」とはどういう意味ですか?セッション変数をクリアすると、そのセッションからクリアされます。ユーザーがその時点からロードしたページには、別のページが再度変数を設定しない限り、変数は表示されません。ここには何かについての誤ったコミュニケーションや誤解がありますが、私はどこで明確ではありません。 –

+0

この詳細ビューを入力すると、セッション変数がアイテムのソートされたリストと共に格納されます。セッション変数をクリアするためにこのビューを離れていることをどのように検出しますか?セッション変数がクリアされない場合は、オプションのセッション変数を設定しないコンテキストからこのビューを入力すると、以前と同じリストコンテキストにユーザーが残ります。 – slypete

1

あなたがやりたいことに応じて、create a custom managerか、new manager methodを追加します。この例では

、あなたは現在のdatetime後の日付で公開されてマークされているブログ記事を選択し、新しいマネージャーを追加します。

from django.db import models 
from datetime import datetime 

class PublishedPostManager(models.Manager): 
    def get_query_set(self): 
     return super(PublishedPostManager, self).get_query_set().filter(published=True, time__lt=datetime.now()) 

class Post(models.Model): 
    title = models.CharField(max_length=128) 
    body = models.TextField() 
    published = models.BooleanField(default=False) 
    time = models.DateTimeField() 

    objects = models.Manager() # Needed to ensure that the default manager is still available 
    published = PublishedPostManager() 

その後、代わりにPost.objects.all()の、あなたはすべてのレコードを取得するためにPost.published.all()を使用することができます。通常のクエリセットメソッドは、同様に使用できます。

Post.published.count() 
Post.published.select_related().filter(spam__iexact='eggs') 
# etc 

そしてもちろん、あなたはまだ、デフォルトのマネージャーを使用することができます。

Post.objects.all() 
+0

あなたの答えをありがとうございます。しかし、私はすでにフィルタリングを実行する方法を知っています。私は、複数のビューにわたって一定のフィルタ状態を維持しようとしています。 – slypete

+0

これは、カスタムマネージャを作成するのとまったく同じです。上記の例では、Post.objects.all()はPostのすべてのインスタンスを返し、Post.published.all()はPublished = Trueおよびtime__lt = datetime.now()のすべてのインスタンスを返します。 Post.publishedを使用するたびにフィルタリングが行われます。変更する場合は、PublishedPostManagerの定義を1か所で行うだけです。 –

+0

混乱があります。私は、カスタムマネージャを使用することがフィルタリングの目的に合っていることに同意します。しかし、私の質問は、この疑問を提起しています。ビューから、使用するカスタムマネージャーはどのように選択するのですか? – slypete

関連する問題