Django 管理中的自定义依赖下拉菜单

BAB*_*BZI 7 javascript django ajax django-admin django-ajax-selects

我有一个按阶段模型的项目外键。我很难在 Django 管理页面中创建依赖的下拉列表。

\n\n

我想当用户从该项目的(项目下拉)阶段选择一个项目时,在第二个下拉菜单中显示

\n\n

实现这一目标的最佳方法是什么?

\n\n

如果下拉列表根据其父级的值来过滤项目,那就太好了。

\n\n

在此输入图像描述

\n\n
class Project(models.Model):\n    name                    = models.CharFieldmax_length = 100, unique= True)\n    short_name              = models.CharField(max_length= 4, unique= True)\n    slug                    = models.SlugField(max_length= 100, allow_unicode=True, null=True, editable= False)\n    location                = models.OneToOneField(Location, on_delete = models.SET_NULL, null= True, blank= False, verbose_name= \'\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\xdb\x8c\xd8\xaa\')\n    start_date              = models.DateField(default= timezone.now, null= True, blank= True)      \n    end_date                = models.DateField(default= timezone.now, null= True, blank= True)\n    duration                = models.IntegerField(default= 0, editable= False)\n\nclass Phase(models.Model):\n    title                = models.CharField(max_length= 20)\n\nclass ProjectPhase(models.Model):\n    project                 = models.ForeignKey(Project, on_delete= models.CASCADE, related_name= \'phase\')\n    phase                   = models.ForeignKey(Phase, on_delete=models.CASCADE, related_name= \'project\')\n    start_date              = models.DateField(default= timezone.now)      \n    end_date                = models.DateField(default= timezone.now)\n    duration                = models.IntegerField(default= 0, editable= True)\n
Run Code Online (Sandbox Code Playgroud)\n

Bla*_*oor 5

1. 在 ModelAdmin 中为 Generaldata 导入一个 js 媒体文件:

class YourModelAdmin(admin.ModelAdmin):    
    form = YourModelForm
    #list_display = ['your fields',]
    class Media:
        js = ("yourapp/selectajax.js",)

admin.site.register(YourModel, YourModelAdmin)
Run Code Online (Sandbox Code Playgroud)

2.创建一个新的js文件,保存yourproject/yourapp/static/yourapp/目录或其他合适的目录。

jQuery(function($){
    $(document).ready(function(){
        $("#id_project_select").change(function(){
            // console.log(obj.currentTarget.value);
            $.ajax({
                url:"/get_phases/",
                type:"POST",
                data:{project: $(this).val(),},
                success: function(result) {
                    console.log(result);
                    cols = document.getElementById("id_phase_select");
                    cols.options.length = 0;
                    for(var k in result){
                        cols.options.add(new Option(k, result[k]));
                    }
                },
                error: function(e){
                    console.error(JSON.stringify(e));
                },
            });
        });
    }); 
});
Run Code Online (Sandbox Code Playgroud)

3.创建一个视图来处理ajax

@login_required
def get_phases(request):
    project = request.POST.get('project')
    phases = {}
    try:
        if project:
            prophases = Project.objects.get(pk=int(project)).phase
            phases = {pp.phase.title:pp.pk for pp in prophases}
    except:
        pass
    return JsonResponse(data=phases, safe=False)
Run Code Online (Sandbox Code Playgroud)

4. 将 'get_phases/ 添加到 urlpatterns。

请注意,您应该根据需要修改一些代码。