在django admin(grappelli或不是grappelli)中过滤有很多值的many2many(或foreignkey)

时间:2012-10-22 15:56:16

标签: django django-admin django-1.4 django-grappelli django-admin-filters

我有两种模式:

class TheMainThing(models.Model):
    ... some fields ...
    type = ManyToManyField('Type')

class Type(models.Model):
    ...more fields...

我想在管理员TheMainThings中启用过滤Types。唯一的问题是有大约100k或更多的Type个对象,所以用标准的内置过滤器做这件事是不实际的。这是因为所有Types都作为可用选项加载到浏览器中。 (实际上,我正在使用Grappelli,但我相信它与标准的Django管理员一样)。

这个问题有* not_reinvent_the_wheel *方法吗?

我喜欢Grappelli在raw_id字段上的自动完成小部件,我想这样的东西对于这个问题来说是理想的......它有这样的东西吗?

修改
澄清一下 - 主要问题是浏览器中的加载时间和内存消耗,而不是表示。

1 个答案:

答案 0 :(得分:0)

管理员将这些过滤器输出为<ul>内的查询字符串的链接。你可以改为选择那些。

那里使用的模板是admin/filter.html,它看起来像这样:

{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
<ul>
{% for choice in choices %}
    <li{% if choice.selected %} class="selected"{% endif %}>
    <a href="{{ choice.query_string|iriencode }}">{{ choice.display }}</a></li>
{% endfor %}
</ul>

您可以使用相同的名称提供自己的名称来覆盖它们,因此重做它可能是这样的:

{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3>
<select>
{% for choice in choices %}
    <option data-href="{{ choice.query_string|iriencode }}"
            {% if choice.selected %} selected="selected"{% endif %}>
    {{ choice.display }}
    </option>
{% endfor %}
</select>

然后按照更改时的过滤器链接:

$(function() {
    $('select', '#changelist-filter').on('change', function(e) {
        window.location = window.location.href + $(e.target).attr('data-href');
    });

});

为了更进一步,你可以在之后用Select2之类的东西对待那些。