【问题标题】:Django: How to refresh table after filtering without refreshing the whole page?Django:如何在过滤后刷新表格而不刷新整个页面?
【发布时间】:2017-06-18 10:09:39
【问题描述】:

问题的根源在于如何动态刷新过滤后的表格,而不刷新整个页面。

我几乎是 python/html/css 的新手,所以请为新手制作一些 cmet [谢谢]。 研究了一下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-filter 来制作过滤表单:

    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 后,整个页面都会用新数据刷新

而且我希望刷新唯一的表。

请给我一个关于如何做的提示。

非常感谢。

【问题讨论】:

  • Ajax 查询/请求
  • 是的,我知道,但我需要一个使用 django-tables/filters 的示例
  • 您是否使用复选框作为过滤器?纽扣?要不然是啥?您可以通过澄清这一点来帮助我们。
  • @AlanAvalos,我使用 django-filters 模块:有两个文本搜索字段和两个下拉菜单。

标签: javascript python django python-3.x


【解决方案1】:

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

【讨论】:

  • 谢谢,我会努力理解的。
猜你喜欢
  • 2014-01-10
  • 2019-09-05
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多