Django - 根据第一个字段实时更新第二个list_filter字段?

时间:2017-06-14 17:25:01

标签: django django-models django-admin django-admin-tools

所以我正在努力提高我的django知识,我正在研究这个个人项目,其中我有两个类别,主要是更一般的类别和子类别过滤器。

一个例子是main_category = smartphone,sub_category = samsung_phones。

我在models.py中的课程将是:

class Products(models.Model):

    product_name = models.CharField(max_length=20)
    main_category = models.CharField(max_length=50)
    sub_category = models.CharField(max_length=50)

我在admin.py中的课程将是:

class ProductsAdmin(ImportExportModelAdmin):
    ...
    list_filter = ['main_category', 'sub_category']
    ...

现在我要做的是,在我的/ admin / page中,我想根据我在'main_category'中选择的内容,实时更改'sub_category'过滤器的内容。这可能吗?因为现在它除了占用空间之外什么都不做,所以有一个main_category过滤器本身是没用的。我认为这应该是一件容易的事,但我找不到任何关于它的文档。

Django版本是1.9.1

1 个答案:

答案 0 :(得分:1)

I would do it with a jQuery injection:

class ProductsAdmin(ImportExportModelAdmin):
    ...
    list_filter = ['main_category', 'sub_category']
    ...

    class Media(object):
        js = (
            'app/js/myscript.js',  # app static folder
        )

If you do not know the data upfront or it changes a lot, and thus are unable to construct a jQuery/javascript function to control the 2 filter elements, you need to override the change_list function and template to inject dynamic js/jQuery.

Or, because I am too lazy and nothing else matters, I would just make a js file, which I would override with the dynamic js everytime you visit the admin page.

EDIT 1: the js file could be something like this (off course this can be much improved, but it is up to you):

// save here your array with data
my_main_category = {
  "": ['Samsung', 'Nokia', 'Dacia', 'Alfa Romeo', 'Volga'], // add them all
  "Smartphones": ['Samsung', 'Nokia'],
  "Cars": ['Dacia', 'Alfa Romeo', 'Volga']
};

// copy options to repopulate sub category select
var $sub_category_options = $('select[data-name="sub_category"] > option').clone();

$('select[data-name="main_category"]').on('change', function () {
    $('select[data-name="sub_category"]').empty().append($sub_category_options);
    $('select[data-name="sub_category"] option').each(function () {
        if ($.inArray($(this).val(), my_main_category[$('select[data-name="main_category"]').val()])) {
            $(this).remove();
        }
    })
});