【问题标题】:How refresh django admin form when a value change in the browser?当浏览器中的值更改时如何刷新 django 管理表单?
【发布时间】:2015-05-09 21:34:45
【问题描述】:

我有一个选择字段,当更改为另一个值时,它必须更改表单中的其他字段。

所以我需要刷新表单,或者使用 ajax 调用更新字段。管理表单可以做到这一点吗?

【问题讨论】:

    标签: ajax django python-3.x django-admin


    【解决方案1】:

    不久前遇到了这个问题。以下是我最终解决它的方法,举个例子,将Buildings 过滤到Floors 过滤到Rooms (Django 2.0.3):

    #admin.py
    class BuildingAdmin(admin.ModelAdmin):
      class Media:
        js = ("jquery-3.3.1.min.js","buildingfilter.js")
    # Your other admin options for fields, filters, etc.
    # The script will use the id's of the fields you included
    # If the filters you want aren't actually FK's in the model,
    #  just use a ModelForm to add extra fields and use those
    #  element id's in the script.
    
    #views.py
    def building(request):
      if request.method == 'GET' and request.is_ajax():
        building_id = request.GET.get('id')
        json_floor = serializers.serialize("json", Floor.objects.filter(fkbuilding_id=building_id))
        return HttpResponse(json_floor, content_type='application/json')
      else:
        return HttpResponse("no-go")
    
    def floor(request):
      if request.method == 'GET' and request.is_ajax():
        floor_id = request.GET.get('id')
        json_room = serializers.serialize("json", Room.objects.filter(fkfloor_id=floor_id))
        return HttpResponse(json_room, content_type='application/json')
      else:
        return HttpResponse("no-go")
    
    #urls.py
    urlpatterns = [
      ...
      path('building/', views.building),
      path('floor/', views.floor),
    ]
    
    #buildingfilter.js
    $(function(){
        //Boilerplate AJAX loading if using cookies
        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]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
        console.log("Cookies loaded");
    }
    var csrftoken = getCookie('csrftoken');
    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        console.log("CRSF Safe");
    }
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });
    //Code that does the filtering
    $("#id_building").on('change', function(e) {
        e.preventDefault();
        console.log($(this).val());
        $.getJSON("http://127.0.0.1:8000/building/",{id: $(this).val()}, function(j) {
            var options = '<option value="">---??---</option>';
            for (var i = 0; i < j.length; i++) {
                options += '<option value="' + parseInt(j[i].pk) + '">' + j[i].fields['name'] + '</option>';
            }
            console.log(options);
            $("#id_floor").html(options);
            $("#id_floor option:first").attr('selected', 'selected');
        });
        $("#id_building").attr('selected', 'selected');
    });
    $("#id_floor").on('change', function(e) {
        e.preventDefault();
        console.log($(this).val());
        $.getJSON("http://127.0.0.1:8000/floor/",{id: $(this).val()}, function(j) {
            var options = '<option value="">---??---</option>';
            for (var i = 0; i < j.length; i++) {
                options += '<option value="' + parseInt(j[i].pk) + '">' + j[i].fields['name'] + '</option>';
            }
            console.log(options);
            $("#id_room").html(options);
            $("#id_room option:first").attr('selected', 'selected');
        });
        $("#id_floor").attr('selected', 'selected');
      });
    });
    

    【讨论】:

      【解决方案2】:

      绝对有可能使用 javascript 在 django admin 中拥有动态字段。

      举个很好的例子,我建议django-smart-selectsdjango-admin-flexselect

      https://github.com/digi604/django-smart-selects

      https://github.com/runekaagaard/django-admin-flexselect

      【讨论】:

        猜你喜欢
        • 2015-02-18
        • 1970-01-01
        • 1970-01-01
        • 2010-11-11
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多