2012-11-28 13 views
10

मैंने django-tables2 (जिसे मैं पहली छाप से अत्यधिक अनुशंसा कर सकता हूं) का उपयोग शुरू किया और मैं खुद से पूछ रहा हूं कि कॉलम फ़िल्टरिंग को कैसे कार्यान्वित किया जाए। मुझे इसके लिए उपयुक्त दस्तावेज नहीं मिला है, लेकिन मुझे यकीन है कि यह कहीं बाहर है।Django टेबल्स - कॉलम फ़िल्टरिंग

उत्तर

23

थोड़ा देर से उत्तर दिया लेकिन वैसे भी ... मुझे कॉलम फ़िल्टरिंग के लिए कोई उचित दस्तावेज़ीकरण भी नहीं मिला। वहाँ यह करने के लिए कई तरीके हैं:

ए हाथ द्वारा: मैं एक प्रपत्र फ़ील्ड्स युक्त जोड़ने के साथ मैं फ़िल्टर करना चाहते हैं और फिर मैं मेरे विचार में कुछ इस तरह करते हैं:

 
    data = models.MyClass.all() 
    form = forms.MyFilterForm(request.GET) 
    if request.GET.get('field1'): 
    data = data.filter(field1=request.GET.get('field1')) 
    if request.GET.get('field2'): 
    data = data.filter(field2=request.GET.get('field2')) 
    ... 
    table = tables.MyTable(data) 

यह बहुत अच्छा काम करता है हालांकि यह इतना DRY नहीं है क्योंकि यह दृश्य में हार्ड कोड है।

 
from django_tables2 import SingleTableView 
class FilteredSingleTableView(SingleTableView): 
    def get_table_data(self): 
    data= 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')) 
    return data 

    def get_context_data(self, **kwargs): 
     context = super(FilteredSingleTableView, self).get_context_data(**kwargs) 
     context['form'] = forms.MyFilterForm(self.request.user, self.request.GET) 
     return context 

यह और अधिक सूखी :) है

सी का प्रयोग SingleTableView और django_filters: एक SingleTableView उस रूप में शामिल है जोड़ने के लिए एक और तरीका है:

बी एक SingleTableView का उपयोग करना: यह शायद सबसे DRY तरीका है :) यहां यह कैसे करें:

पहले फ़िल्टर को परिभाषित करें:

 
class MyFilter(django_filters.FilterSet): 
    field1 = django_filters.CharFilter() 
    field2 = django_filters.CharFilter() 
... 

(या आप एक मॉडल फिल्टर मेटा (मॉडल = MyModel)

में अब जोड़ सकते हैं, जैसे एक SingleTableView बनाने इस

 
class FilteredSingleTableView(SingleTableView): 
    def get_table_data(self): 
    f = filters.MyFilter(self.request.GET, queryset =models.MyClass.objects.all() , request=self.request) 
    return 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 
    return context 

(शायद वहाँ लाइन च के साथ एक समस्या है = ... लेकिन मैं इसे अन्यथा काम नहीं कर सका।

अंत में, आप SingleTableView अपने urls.py से इस

 
url(r'^$', views.FilteredSingleTableView.as_view(
    table_class = tables.MyTable, 
    model=models.MyClass, 
    template_name ='mytemplate.html', 
    table_pagination={ "per_page":50 })) , 
    name='filtered_single_table_view' 
), 

डी की तरह एक सामान्य वर्ग का उपयोग करते हुए कॉल कर सकते हैं: इस तरह की तरह एक और भी अधिक सूखी और Django-सामान्य-वर्ग-बार देखा गया है ! यह वास्तव में सी से अगले कदम है: बस की घोषणा इस तरह से अपनी FilteredSingleTableView: तो तुम दूसरे के बीच अपने urls.py में इसे पारित कर सकते हैं

 
class FilteredSingleTableView(django_tables2.SingleTableView): 
    filter_class = None 

    def get_table_data(self): 
    self.filter = self.filter_class(self.request.GET, queryset =super(FilteredSingleTableView, self).get_table_data()) 
    return self.filter.qs 

    def get_context_data(self, **kwargs): 
    context = super(FilteredSingleTableView, self).get_context_data(**kwargs) 
    context['filter'] = self.filter 
    return context 

अब FilteredSingleTableView फिल्टर के वर्ग के लिए एक पैरामीटर है पैरामीटर:

 
    url(r'^$', ships.views.FilteredSingleTableView.as_view(
     model=models.MyModel, 
     table_class=tables.MyTable, 
     template_name='mytemplate.html' , 
     filter_class = filters.MyFilter, 
    ) , name='myview'), 

तो आप अपने मॉडल के किसी भी छानने के लिए संशोधन के बिना FilteredSingleTableView उपयोग कर सकते हैं !!

यह भी ध्यान दें कि मैं अब एक उदाहरण चर के रूप में फिल्टर बचाया और दोहराव कोड f=filters.MyFilter(...) कि मैं सी (get_table_data get_context_data से पहले कहा जाता है में था हटा दिया है - अगर है कि हमेशा ऐसा तो हम एक जोड़ सकता है नहीं था get_filter उदाहरण विधि जो चाल करेगी)!

अपडेट 23/04/2016: लोकप्रिय मांग के बाद, मैंने एक साधारण Django प्रोजेक्ट बनाया है जो पुस्तकों की एक तालिका को फ़िल्टर करने के लिए जेनेरिक FilteredSingleTableView क्लास का उपयोग करता है। आपको कम से यह पता लगाना हो सकता है: https://github.com/spapas/django_table_filtering

अद्यतन 2016/05/07: कृपया ध्यान दें कि आप डी में get_table_data वापसी के लिए return self.filter.qs का उपयोग करना चाहिए (मैं alread इस के साथ जवाब को नवीनीकृत किया है) या फिर दृश्य बहुत लंबा बड़ा तालिकाओं के लिए प्रस्तुत करने के लिए ले जाएगा - अधिक जानकारी के https://github.com/spapas/django_table_filtering/issues/1

3

पर पाया जा सकता एक सामान्य दृश्य है कि यह निर्माण करने के लिए एक आसान और ड्रायर तरीका नहीं है:

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 
0

आप Django के ListView या एक उपवर्ग उसके (SingleTableView बजाय) मैं निम्नलिखित सुझाव के साथ मिलकर django_tables2.views.SingleTableMixin उपयोग करने के लिए पसंद करते हैं:

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 के लिए युग्मित नहीं किया जा रहा की अतिरिक्त लाभ है (डीआरवाई एफटीडब्ल्यू) जिसका अर्थ है कि इसका उपयोग जेनेरिक ListViews के साथ भी किया जा सकता है।

संबंधित मुद्दे