私はdjango-tables2 (最初の印象から強くお勧めできます) の使用を開始し、列フィルタリングの実装方法を自問自答しています。適切なドキュメントは見つかりませんが、どこかにあると確信しています。
4 に答える
少し遅い答えですが、とにかく...列フィルタリングに関する適切なドキュメントも見つかりませんでした。それを行うには多くの方法があります:
A. 手動: フィルター処理するフィールドを含むフォームを追加し、ビューで次のようにします。
データ = models.MyClass.all()
フォーム = フォーム.MyFilterForm(request.GET)
request.GET.get('field1') の場合:
data = data.filter(field1=request.GET.get('field1') )
request.GET.get('field2') の場合:
data = data.filter(field2=request.GET.get('field2') )
...
テーブル = テーブル.MyTable(データ)
これは非常にうまく機能しますが、ビューでハードコーディングされているため、それほど DRY ではありません。
B. SingleTableView の使用: もう 1 つの方法は、次のフォームを含む SingleTableView を追加することです。
django_tables2からSingleTableViewをインポート
クラス FilteredSingleTableView(SingleTableView):
def get_table_data(self):
データ = models.MyClass.objects.all
if self.request.GET.get('field1'):
data = data.filter(field1=self.request.GET.get('field1') )
if self.request.GET.get('field1'):
data = data.filter(field1=self.request.GET.get('field1') )
データを返す
def get_context_data(self, **kwargs):
context = super(FilteredSingleTableView, self).get_context_data(**kwargs)
context['form'] = forms.MyFilterForm(self.request.user, self.request.GET)
コンテキストを返す
これはもっとドライです:)
C. SingleTableView と django_filtersの使用: これはおそらく最も DRY な方法です :) 方法は次のとおりです。
最初にフィルターを定義します。
クラス MyFilter(django_filters.FilterSet): field1 = django_filters.CharFilter() field2 = django_filters.CharFilter() ...
(または、メタ (モデル = MyModel) にモデル フィルターを追加できます)
次に、このような SingleTableView を作成します
クラス FilteredSingleTableView(SingleTableView):
def get_table_data(self):
f = filters.MyFilter(self.request.GET, queryset =models.MyClass.objects.all() , request=self.request )
fを返す
def get_context_data(self, **kwargs):
context = super(FilteredSingleTableView, self).get_context_data(**kwargs)
f = filters.MyFilter(self.request.GET, queryset =models.MyClass.objects.all() , request=self.request )
context['form'] = f.form
コンテキストを返す
(おそらく f =... という行に問題がありますが、それ以外の方法では機能させることができませんでした。
最後に、このように urls.py から SingleTableView を呼び出すことができます
url(r'^$', views.FilteredSingleTableView.as_view(
table_class = テーブル.MyTable,
モデル=models.MyClass、
template_name ='mytemplate.html',
table_pagination={ "per_page":50 } )) ,
name='filtered_single_table_view'
)、
D. ジェネリック クラスの使用:これはさらに DRY であり、django-generic-class-views のような方法です! これは実際にはCからの次のステップです: FilteredSingleTableView を次のように宣言するだけです:
クラス FilteredSingleTableView(django_tables2.SingleTableView):
filter_class = なし
def get_table_data(self):
self.filter = self.filter_class(self.request.GET, queryset =super(FilteredSingleTableView, self).get_table_data() )
self.filter.qs を返す
def get_context_data(self, **kwargs):
context = super(FilteredSingleTableView, self).get_context_data(**kwargs)
context['filter'] = self.filter
コンテキストを返す
FilteredSingleTableView にはフィルターのクラスのパラメーターがあるため、他のパラメーターの中で urls.py に渡すことができます。
url(r'^$', ship.views.FilteredSingleTableView.as_view(
モデル=models.MyModel,
table_class=tables.MyTable,
template_name='mytemplate.html' ,
filter_class = フィルター.MyFilter,
) 、name='myview')、
したがって、モデルをフィルタリングするために、変更を加えることなく FilteredSingleTableView を使用できます!!
また、フィルタをインスタンス変数として保存し、 Cf=filters.MyFilter(...)で作成した反復コードを削除したことにも注意してください (get_table_data は get_context_data の前に呼び出されます。常にそうであるとは限らない場合は、このトリックを実行するインスタンス メソッドを追加できます)。 ) !get_filter
2016 年 4 月 23 日更新: 一般的な要望に応えて、一般的な FilteredSingleTableView クラスを使用して本のテーブルをフィルター処理する単純な Django プロジェクトを作成しました。https://github.com/spapas/django_table_filteringで見つけることができます。
更新 05/07/2016 : Dreturn self.filter.qsのget_table_dataリターンに使用する必要があることに注意してください(私はこれで回答を更新しました)。そうしないと、大きなテーブルのレンダリングに時間がかかりすぎます。詳細については、https://github.com/spapas/django_table_filtering/issues/1
一般的なビューを構築するためのより簡単でドライな方法があります。
from django_filters.views import FilterView
from django_tables2 import SingleTableView
class FilterTableView(FilterView, SingleTableView):
def get_table_data(self):
return self.object_list
だからあなたはこれを行うことができます:
class MyTableView(FilterTableView):
model = MyModel
table_class = MyTable
filterset_class = MyFilter
django_tables2.views.SingleTableMixin( ではなく) DjangoListViewまたはそのサブクラスと組み合わせて使用したい場合SingleTableViewは、次のことをお勧めします。
class FilteredListViewMixin(object):
""" Uses django-filter to filter a ListView. """
filter_class = None
def get_queryset(self):
qs = super(FilteredListViewMixin, self).get_queryset()
self.filter = self.filter_class(self.request.GET,
queryset=qs)
return self.filter.qs
def get_context_data(self, **kwargs):
context = super(FilteredListViewMixin, self).get_context_data(**kwargs)
context['filter'] = self.filter
return context
django-tables2(DRY FTW)に結合されないという追加の利点があります。つまり、ジェネリックでListViewsも使用できます。