【问题标题】:Django Admin: populate the field based on previous field valueDjango Admin:根据先前的字段值填充字段
【发布时间】:2013-02-10 14:19:20
【问题描述】:

我在 django admin 中有一个模型如下

ChoiceA= (
      ("on-false","on-false"),
       ("on-true","on-true"),
     )

ChoiceB =  (
        ("always","always"),
        ("never","never"),
       )
   id = models.CharField(verbose_name="Field",max_length=32)
   type = models.CharField(verbose_name="Expression",max_length=32)
   action = models.CharField(max_length=32, choices=x)

现在基于用户输入的类型,即如果用户输入 type = "a",那么操作的选项应该设置为 ChoiceA,如果用户输入 type =“b”,那么操作的选项应该设置为 ChoiceB。如何在 Django Admin 中实现这一点?

编辑:

action_change.js

jQuery(document).ready(function(){
$("#id_type").change( function(event) {
$.ajax({
        "type"     : "POST",
        "url"      : "/action_choices/",
        "dataType" : "json",
        "cache"    : false,
        "error"   :  alert("hello"),  
        "success"  : function(json) {
            $('#id_action >option').remove();
            for(var j = 0; j < json.length; j++){
                $('#id_action').append($('<option></option>').val(json[j][0]).html(json[j][1]));
            }
        }

});
});
});

【问题讨论】:

  • 如果type字段只有两个选择,为什么不为type字段定义choices

标签: django django-admin


【解决方案1】:

您可以使用 Ajax 和 jQuery 来实现它:

models.py:

type   = models.CharField(verbose_name="Expression",max_length=32)
action = models.CharField(max_length=32, choices = (('', ''), ))

admin.py:

class MyModelAdmin(admin.ModelAdmin):
    list_display = ('type', )

    class Media:
        js = ['/static/js/action_change.js']

admin.site.register(MyModel, MyModelAdmin)

urls.py:

url(r'^action_choices/', 'myproject.myapp.views.action_choices'),

views.py:

def action_choices(request): 
    action_list = []
    ChoiceA = ("on-false", "on-true")
    ChoiceB = ("always", "never")

    action_type = request.GET.get('action_type')
    if str(action_type).lower() == 'a':
        choices = ChoiceA
    elif str(action_type).lower() == 'b':
        choices = ChoiceB
    else:
        choices = ()

    [action_list.append((each,each)) for each in choices]
    json = simplejson.dumps(action_list)
    return HttpResponse(json, mimetype='application/javascript')

在您的静态文件夹中创建具有以下内容的文件action_change.js 并在ModelAdminclass Media 中定义正确的路径。

action_change.js

(function($){   
    $(function(){
        $(document).ready(function() {
            $('#id_type').bind('keyup', type_change);           
            $('#id_action >option').show();
        });
});  
})(django.jQuery);

// based on the type, action will be loaded

var $ = django.jQuery.noConflict();

function type_change()
{
    var action_type = $('#id_type').val();
    $.ajax({
            "type"     : "GET",
            "url"      : "/action_choices/?action_type="+action_type,
            "dataType" : "json",
            "cache"    : false,
            "success"  : function(json) {
                $('#id_action >option').remove();
                for(var j = 0; j < json.length; j++){
                    $('#id_action').append($('<option></option>').val(json[j][0]).html(json[j][1]));
                }
            }           
    })(jQuery);
}

这应该适用于您询问的场景。我在下面给出我的建议:

models.py

type   = models.CharField(verbose_name="Expression",max_length=32, choices = (('a', 'a'), ('b', 'b'), ))
action = models.CharField(max_length=32, choices = (('', ''), ))

action_change.js(第 5 行)

$('#id_type').bind('change', type_change);

【讨论】:

  • 实际上当我按照你所说的那样尝试时,操作字段没有加载。所以我改变了 action_change.js 文件如下。但现在它给出了对象 [object Window] 的 Property 'jQuery' is not a function
  • 只有在type字段中有值时才会加载action字段。
  • 您能否编辑我粘贴的上述代码并使用正确的解决方案
  • 您在使用我的代码时遇到了什么问题?如果你能解释清楚,我可以更好地帮助你。
  • 当我选择一种类型时,相应的动作不会被加载。操作字段保持空白,其中有一个空白选项。没有显示错误。
【解决方案2】:

您必须用所有可能的选择来初始化action 字段,否则 Django 会抱怨以前不存在的选择不是有效的选择。

我的建议是使用所有可能的选项初始化该字段,并使用 JavaScript 切换选项的可见性,具体取决于 type 的值。有一些插件可以处理 Django admin 中的动态字段,但我见过的大多数插件都处理需要查找的 ForeignKey 或 ManyToMany 字段。

您最好通过Media 元类将一些 JavaScript 添加到您的管理表单并自己处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多