2017-02-01 4 views
-1

Der Grund des Problems besteht darin, wie die gefilterte Tabelle dynamisch aktualisiert wird, ohne die gesamte Seite zu aktualisieren.Django: Wie wird die Tabelle nach dem Filtern aktualisiert, ohne die gesamte Seite zu aktualisieren?

Ich bin fast Anfänger in Python/html/css, also bitte machen Sie einige Kommentare wie für einen Neuling [Danke]. Nach einiger Forschung auf StackOverFlow, fand ich, dass es mit js gemacht werden konnte, aber ich habe fast keine Erfahrung mit js und ich weiß nicht, wie man es in Django benutzt.

Gibt es eine Möglichkeit, nur Django-Tools zu verwenden? Und wie effizient wäre es? Vielleicht können Sie einige Beispiele zur Behebung des Problems angeben. Hier

ist das Modell:

class Player(models.Model): 
    last_name = models.CharField(
     null=True, 
     blank=True, 
     max_length=255, 
     verbose_name="прізвище" 
    ) 
    first_name = models.CharField(
     null=True, 
     blank=True, 
     max_length=255, 
     verbose_name="ім'я" 
    ) 
    city = models.ForeignKey(
     City, 
     on_delete=models.SET_NULL, 
     null=True, 
     blank=True, 
     verbose_name="місто" 
    ) 
    rating = models.PositiveIntegerField(
     null=True, 
     blank=True, 
     verbose_name="рейтинг" 
    ) 
    rank = models.ForeignKey(
     Rank, 
     on_delete=models.SET_NULL, 
     null=True, 
     blank=True, 
     verbose_name="ранг" 
    ) 
    local_rank = models.ForeignKey(
     LocalRank, 
     null=True, 
     blank=True, 
     on_delete=models.SET_NULL, 
     verbose_name="розряд" 
    ) 

def __str__(self): 
    if self.last_name and self.first_name: 
     return self.last_name + ' ' + self.first_name 
    elif self.egd_last_name and self.egd_first_name: 
     return self.egd_last_name + ' ' + self.egd_first_name 
    else: 
     return self.id 

Ich bin mit django-tables2 die Tabelle zu machen:

class PlayerTable(tables.Table): 
    full_name = tables.LinkColumn(
     accessor="__str__", 
     verbose_name="Прізвище та ім'я", 
     order_by="last_name", 
     viewname='UGD:player_info', 
     empty_values=(), 
     args=[A('pk')] 
    ) 
    local_rank = tables.Column(
     accessor="local_rank.abbreviate", 
     order_by="id" 
    ) 
    ufgo_member = tables.BooleanColumn(
     verbose_name="Член УФГО" 
    ) 

    class Meta: 
     model = Player 
     fields = (
      'id', 
      'full_name', 
      'city', 
      'rating', 
      'rank', 
      'local_rank', 
      'ufgo_member' 
     ) 
     attrs = {'class': 'main'} 

Ich bin mit django-Filter, um eine Filterform zu machen:

class PlayersFilter(django_filters.FilterSet): 
    last_name = django_filters.CharFilter(
     lookup_expr='contains', 
     label="Прізвище" 
    ) 
    first_name = django_filters.CharFilter(
     lookup_expr='contains', 
     label="Ім'я" 
    ) 
    city = django_filters.ChoiceFilter(
     choices=[(city.id, city.name) for city in City.objects.all()], 
     empty_label="--Не обрано--", 
     label="Місто" 
    ) 
    ufgo_member = django_filters.ChoiceFilter(
     choices=[ 
      (False, 'Ні'), 
      (True, 'Так') 
     ], 
     name="ufgo_member", 
     label="Член УФГО", 
    ) 

    class Meta: 
     model = Player 
     fields = (
      'last_name', 
      'first_name' 
     ) 

Die f Das Problem ist - Ansicht/Vorlage.

Ich bin mit SingleTableMixin und FilterView meiner Ansicht nach der Tabelle und Filter kümmern:

class RatingListView(SingleTableMixin, FilterView): 
    table_class = PlayerTable 
    table_pagination = False 
    template_name = 'UGD/rating_list.html' 
    filterset_class = PlayersFilter 

Hier habe ich eine Idee, um die Sicht auf mehrere Teile zu teilen, aber ich ziehe immer noch‘ Ich weiß, wie es geht. Vielleicht haben Sie einige Vorschläge, um es besser zu machen?

Meine Vorlage:

<body> 
    <div class="filter"> 
     <form id="filter_submit" class="filter"> 
      {% block content %} 
       <div class="filter"> 
        <table class="filter"> 
         {{ filter.form.as_table }} 
        </table> 
        <button id="filter_submit_button" type="submit">OK</button> 
       </div> 
      {% endblock %} 
     </form> 
    </div> 
    <div> 
     {% render_table table %} 
    </div> 
</body> 

Ich glaube, ich sollte ein Skript hinzufügen, aber ich weiß nicht, wie js noch verwenden.

Das Problem: Nach dem Filter und die OK-Taste, die ganze Seite wird aktualisiert mit neuen Daten

Und ich will, dass nur Tisch aufgefrischt war chosing.

Bitte geben Sie mir einen Hinweis, wie es geht.

Vielen Dank.

+0

Ajax Anfragen/Anfragen – Sayse

+0

Yep, Ich weiß, aber ich brauche ein Beispiel mit der Verwendung von Django-Tabellen/Filter – jumpman24

+0

Verwenden Sie Kontrollkästchen als fi Filter? Tasten? Oder was? Sie können uns helfen, indem Sie das klären. –

Antwort

0

Mit Blick auf die Django-Filter-Dokumentation (https://django-filter.readthedocs.io/en/develop/index.html), diese App macht die Filterung im Back-End. Ich habe keinen JavaScript-Code gesehen, der ausgeführt wurde, und er behandelt die Filterlogik in den Ansichten. Aus diesem Grund muss die App die Seite aktualisieren, um Ihnen die gefilterte Tabelle anzuzeigen.

Ich empfehle Ihnen, die Filterfunktionalität mit Javascript zu implementieren. Sie müssen die Elemente der Tabelle, die Sie filtern möchten, die Triggerelemente (Dropdown-Felder und Suchfelder, wie im Django-Filter) identifizieren und beide verknüpfen, um Änderungen am DOM vorzunehmen.Auf diese Weise können Sie einen dynamischen Tabellenfilter erstellen.

Diese können paar Links, die Sie mit diesem loszulegen:

http://www.w3schools.com/howto/howto_js_filter_table.asp

http://codepen.io/abocati/pen/vdKce [1]

[1] JS

(function(document) { 
'use strict'; 

var LightTableFilter = (function(Arr) { 

    var _input; 
var _select; 

    function _onInputEvent(e) { 
     _input = e.target; 
     var tables = document.getElementsByClassName(_input.getAttribute('data-table')); 
     Arr.forEach.call(tables, function(table) { 
      Arr.forEach.call(table.tBodies, function(tbody) { 
       Arr.forEach.call(tbody.rows, _filter); 
      }); 
     }); 
    } 

    function _onSelectEvent(e) { 
     _select = e.target; 
     var tables = document.getElementsByClassName(_select.getAttribute('data-table')); 
     Arr.forEach.call(tables, function(table) { 
      Arr.forEach.call(table.tBodies, function(tbody) { 
       Arr.forEach.call(tbody.rows, _filterSelect); 
      }); 
     }); 
    } 

    function _filter(row) { 

     var text = row.textContent.toLowerCase(), val = _input.value.toLowerCase(); 
     row.style.display = text.indexOf(val) === -1 ? 'none' : 'table-row'; 

    } 

    function _filterSelect(row) { 

     var text_select = row.textContent.toLowerCase(), val_select = _select.options[_select.selectedIndex].value.toLowerCase(); 
     row.style.display = text_select.indexOf(val_select) === -1 ? 'none' : 'table-row'; 

    } 

    return { 
     init: function() { 
      var inputs = document.getElementsByClassName('light-table-filter'); 
      var selects = document.getElementsByClassName('select-table-filter'); 
      Arr.forEach.call(inputs, function(input) { 
       input.oninput = _onInputEvent; 
      }); 
      Arr.forEach.call(selects, function(select) { 
    select.onchange = _onSelectEvent; 
      }); 
     } 
    }; 
})(Array.prototype); 

document.addEventListener('readystatechange', function() { 
    if (document.readyState === 'complete') { 
     LightTableFilter.init(); 
    } 
}); 

})(document); 
+0

Danke, ich werde versuchen, das zu verstehen. – jumpman24

Verwandte Themen