代码之家  ›  专栏  ›  技术社区  ›  fabio

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

  •  0
  • fabio  · 技术社区  · 8 年前

    在我的管理中,我需要一个选择字段,该字段根据用户在另一个管理字段中的选择进行选择,因此我认为我必须使用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_affiliation 与内联显示 myuser 它只有一个字段: affiliation . 当我选择此字段的值时(因此我选择附属实例),我希望另一个字段出现(或变为活动): title . 在这个新领域我不想 Title 实例,但仅具有 society 字段UGAL到 社会 的字段 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 回复  |  直到 8 年前
        1
  •  0
  •   fabio    8 年前

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

    我的 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 }})