Django: Как обновить таблицу после фильтрации без обновления всей страницы?

-4

Корень проблемы заключается в том, как динамически обновлять отфильтрованную таблицу без обновления всей страницы.

Я почти новичок в python/html/css, поэтому, пожалуйста, сделайте несколько комментариев, как для новичков [Спасибо]. После некоторого исследования StackOverFlow я обнаружил, что это можно сделать с помощью js, но у меня почти нет опыта работы с js, и я не знаю, как его использовать в Django.

Есть ли возможность использовать только инструменты Django? И насколько это было бы эффективно? Возможно, вы можете привести несколько примеров решения проблемы.

Вот модель:

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

Я использую django-tables2 для отображения таблицы:

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'}

Я использую фильтр django для создания формы фильтра:

    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'
)

Ниже приведена проблема - просмотр/шаблон.

Я использую SingleTableMixin и FilterView, чтобы позаботиться о таблице и фильтре:

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

Здесь у меня есть идея разделить представление на несколько частей, но я до сих пор не знаю, как это сделать. Может быть, у вас есть предложения по улучшению?

Мой шаблон:

<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>

Я думаю, что я должен добавить скрипт, но пока не знаю, как использовать js.

Проблема: после выбора фильтров и нажатия OK вся страница обновляется новыми данными

И я хочу, чтобы только таблица была обновлена.

Пожалуйста, дайте мне подсказку о том, как это сделать.

Большое спасибо.

спросил(а) 2017-02-01T18:30:00+03:00 3 года, 9 месяцев назад
0
81

Если посмотреть на документацию django-filter (https://django-filter.readthedocs.io/en/develop/index.html), это приложение выполняет фильтрацию в фоновом режиме. Я не видел никакого кода javascript, выполненного для этого, и он обрабатывает логику фильтрации в представлениях. Таким образом, для чего приложение должно обновить страницу, чтобы показать вам отфильтрованную таблицу.

Я порекомендую вам реализовать функциональность фильтрации с помощью javascript. Вам нужно идентифицировать элементы таблицы, которые вы хотите фильтровать, триггерные элементы (выпадающие списки и поля поиска, как в django-filter), и связать их оба, чтобы внести изменения в DOM. Таким образом, вы можете иметь динамический фильтр таблицы.

Эти две ссылки помогут вам начать с этого:

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);

ответил(а) 2017-02-02T00:16:00+03:00 3 года, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема