在django-admin中使用javascript过滤字段(内部工作示例)

时间:2018-02-02 18:02:40

标签: javascript django django-admin

在我的管理员中,我想要一个基于另一个管理员字段中用户选择的选择字段,所以我想我必须使用javascript。

这是我的models.py(简化):

class Society(models.Model):
    name = models.CharField(max_length=32, unique=True)


class Title(models.Model):
    name = models.CharField(max_length=32, unique=True)
    society = models.ForeignKey(Society, on_delete=models.PROTECT)


class Affiliation(models.Model):
    society = models.ForeignKey(Society, on_delete=models.PROTECT)


class Myuser(User_Add, BaseUser):
    ...
    affiliation = models.ManyToManyField(Affiliation, through='User_affiliation')
    ...


class User_affiliation(models.Model):
    myuser = models.ForeignKey(Myuser, on_delete=models.CASCADE)
    affiliation = models.ForeignKey(Affiliation, null=True, on_delete=models.CASCADE)
    title = models.ForeignKey(Title, on_delete=models.CASCADE)

我的admin.py

class User_affiliationInline(admin.TabularInline):
    model = User_affiliation
    extra = 0

    class Media:
        js = ("javascript.js",)    

class MyuserAdmin(admin.ModelAdmin):
    inlines = [User_affiliationInline]

User_affiliationmyuser内联显示,并且只有一个字段:affiliation。当我选择此字段的值(因此我选择Affiliation实例)时,我希望另一个字段显示(或变为活动状态):title。在这个新字段中,我不希望所有Title个实例,只有society字段的society实例的Affiliation字段选择。

首先是编写javascript函数。在我的javascript.js

var jQuery = django.jQuery;
jQuery(document).on('formset:added', function(event, $row, formsetName) {
    if (formsetName == 'myuser_user_affiliation') {
        document.getElementById('id_myuser_user_affiliation-0-affiliation').addEventListener('change', function() {
            console.log('changed')
        });
    }
});

这项工作,但后来呢?

1 个答案:

答案 0 :(得分:0)

完成!我的解决方案。请检查错误和改进。

我的javascript.js

var jQuery = django.jQuery;

//to send a csrftoken
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
jQuery.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader('X-CSRFToken', csrftoken);
        }
    }
});


//on pageshow I filter the title_field already present
window.addEventListener('pageshow', function() {
    if (document.getElementById('id_user_user_affiliation-TOTAL_FORMS')) {
        var affiliation_number=document.getElementById('id_user_user_affiliation-TOTAL_FORMS').value
    } else {
        var affiliation_number=0
    };
    if (affiliation_number>0) {
        set_title_field(affiliation_number)
        add_affiliation_Listener(affiliation_number)
    };


    //when I add a new line I filter the new field
    jQuery(document).on('formset:added', function(event, $row, formsetName) {
        if (formsetName == 'user_user_affiliation') {
            affiliation_number=document.getElementById('id_user_user_affiliation-TOTAL_FORMS').value
            var affiliation_id='id_user_user_affiliation-'+(affiliation_number-1)+'-affiliazione';
            set_new_title_field(affiliation_id)
            add_new_affiliation_Listener(affiliation_id)
        };
    });

})


//function to filter all the fields present on page show (I use a unique ajax request)
function set_title_field(affiliation_number) {
    var affiliation_list=[]
    for (var i=0; i<affiliation_number; i++) {
        var affiliation_id='id_user_user_affiliation-'+i+'-affiliazione';
        var affiliation=document.getElementById(affiliation_id).value
        if (affiliation) {
            affiliation_list.push(affiliation)
        } else {
            var title_id='id_user_user_affiliation-'+i+'-title';
            document.getElementById(title_id).disabled = true;
        };
    };
    if (!affiliation_list==[]) {
        var affiliation_index=JSON.stringify(affiliation_list)
        jQuery.ajax({type: 'POST',
            url: '/affiliation-title/',
            data: {
                affiliation_list: affiliation_index
            },
            success: function (lista) {
                if (lista.result === 'OK') {
                    var titles_dict=lista.data.titles_dict;
                    for (var i=0; i<affiliation_list.length; i++) {
                        var titles_list=titles_dict[affiliation_list[i]];
                        var title_id='id_user_user_affiliation-'+i+'-title';
                        var title_field=jQuery('#'+title_id);
                        var title_value=title_field.val();
                        title_field.empty()
                        title_field.append('<option value="">--------</option>')
                        for (var j=0; j<titles_list.length; j++)  {
                            title_field.append('<option value="'+titles_list[j][1]+'">'+titles_list[j][0]+'</option>')
                        };
                        if (title_value) {
                            title_field.val(title_value).prop("selected", true);
                        } else {
                            title_field.val('').prop("selected", true);
                        };
                    };

                };
            }
        });
    };
};


//function to add listener to the field for filter the field at change event
function add_affiliation_Listener(affiliation_number) {
    for (var i=0; i<affiliation_number; i++) {
        var affiliation_id='id_user_user_affiliation-'+i+'-affiliazione';
        document.getElementById(affiliation_id).addEventListener('change', function(event) {
            set_new_title_field(event.target.id)
        });
    };
};


//function to filter a single field (onchange or on add)
function set_new_title_field(affiliation_id) {
    var affiliation_list=[]
    var affiliation=document.getElementById(affiliation_id).value
    var title_id=affiliation_id.replace('affiliazione', 'title')
    var title_field=jQuery('#'+title_id)
    if (affiliation) {
        affiliation_list.push(affiliation)
    } else {
        title_field.val('').prop('selected', true);
        document.getElementById(title_id).disabled = true;
    };

    if (affiliation_list.length>0) {
        var affiliation_index=JSON.stringify(affiliation_list)
        jQuery.ajax({type: 'POST',
            url: '/affiliation-title/',
            data: {
                affiliation_list: affiliation_index
            },
            success: function (lista) {
                if (lista.result === 'OK') {
                    var titles_dict=lista.data.titles_dict;
                    var titles_list=titles_dict[affiliation_list[0]];
                    document.getElementById(title_id).disabled = false;
                    title_field.empty()
                    title_field.append('<option selected="selected" value="">--------</option>')
                    for (var i=0; i<titles_list.length; i++)  {
                        title_field.append('<option value="'+titles_list[i][1]+'">'+titles_list[i][0]+'</option>')
                    };

                };
            }
        });
    };
};


//function to add a listener for the new line
function add_new_affiliation_Listener(affiliation_id) {
    document.getElementById(affiliation_id).addEventListener('change', function(event) {
        set_new_title_field(event.target.id)
    });
};

我的views.py

def affiliation_title(request):
    titles_dict={}
    if request.is_ajax():
        affiliation_list=request.POST.get('affiliation_list')
        affiliation_list=json.loads(affiliation_list)
        for aff_id in affiliation_list:
            title_list=[]
            titles_dict[aff_id]=title_list
            affiliation_selected=affiliation.Affiliation.objects.get(id=int(aff_id))
            society_selected=affiliation_selected.society
            title_list_obj=affiliation.Title.objects.filter(society=society_selected)
            for title in title_list_obj:
                title_list.append((title.name, title.id))
    return JsonResponse({'result': 'OK', 'data': { 'titles_dict': titles_dict }})