zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Django学习11 -- Admin页面级联选择

django学习 -- 页面 选择 11 admin 级联
2023-09-14 09:10:54 时间

系统用的越多问题也就越多,用户提出的要求也越多,问题和要求积攒多了总有撑不住的时候,只得重新筛选问题进行维护。
偷懒并不总是能“有效躲避”问题,学习还要继续、继续。。。。。。

问题描述:Admin页面级联选择

解决方案

解决方案1:django-smart-selects -- 《Django学习8 -- 添加个人应用》中提到过这种方法。
                    应用在python早期版本,python3版本需要对源码进行修改,对数据库设计的级联关系也有要求。 -- 一直未实际应用

解决方案2:使用JS(JQuery,Ajax)对页面数据进行处理
                    不常用此技术,从网上照抄了代码,照葫芦画瓢,进行修改
                    参考文档 -- https://blog.csdn.net/lsysafe/article/details/83051352,)

  1. 建将并寻找存储字段关联关系,此处使用 project  和 task 进行说明(一个project可以有多个task)
  2. 使用django admin后台管理程序生成页面(如下图):建model -- admin注册 -- admin生成页面 -- view处理页面数据显示逻辑
  3. 确认级联关系:当选择 project 时,task 中只显示与 project 相关联的数据
  4. view页面处理数据逻辑
     
    ## get task list by select project in page
    def gettasks(request):
        if request.method == 'GET':   -- 当project选择值变化时,get到对应的值
                                      -- post方法是否可用?没研究
            project=request.GET.get('selpro')    -- 页面ajax data数据设置
            if project:
                data = list(Task.objects.filter(project=project).values("taskname"))  -- get task by select project                
                return JsonResponse(data, safe=False)

     

  5. Get方法获取参数,需要对view方法配置对应的URL
        url('gettask/', view.gettasks,name='gettask'), -- 与veiw方法对应
  6. 设计页面,此处使用 Admin 框架自带后台管理页面模板 -- 参考 django Templates的使用
    * 在Template目录下新建change_form.html页面,对Admin change_from.html进行扩展(为了方便管理建将了对应的application目录)
    * 扩展 after_field_sets模块,在页面初始化模块完成后、操作页面元素时对操作和数据进行处理
    * 获取页面元素ID(与实际models中设置相关):project -- id_project, task -- id_task
    * html页面处理
    {% extends "admin/change_form.html" %}  -- 扩展原有页面,django Template灵活性体现
    {% load i18n admin_urls static admin_modify %}
    
    {% block after_field_sets %}  -- 扩展对应模块;
                                  -- 是否可以在其他模块处理,同样可以对页面进行处理,未做尝试
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
     <script type="text/javascript">
    
        $("#id_project").change(function() {   -- 在project选项变化时触发方法
          var selpro = $(this).val();
             {#alert(selpro);#}
    
          $.ajax({
            url: '/gettask/',              -- 使用get方法设置变化的project URL串;照抄,原理不明
                data:{"selpro":selpro},    -- 获取选中的project;此处与veiw中get方法一致
             type: 'GET',                  -- POST?
             dataType: 'json',
             success: function (data) {    -- 获取数据成功对显示内容进行处理
                var content='';
                 $.each(data, function(i, item){
                      content+='<option value='+item.taskname+'>'+item.taskname+'</option>';
                                           -- 生成Task数据为{key:value}字典
                    });
                $('#id_task').html(content) -- 显示task到对应的元素ID;照抄,原理不明
            },
          })
    	   .fail(function(){              -- 处理异常,当选择无效时显示;error呢?
                var content='';
                content+='<option value= task> --------- </option>';
                $('#id_task').html(content)
    		  });
        });
    </script>
    {% endblock %}

     

问题回顾:从最初设计系统开始,这个问题应一直存在,一直以不会、不熟悉拖延着。后来使用时总是出现对应关联关系选择错误的情况,使用者反应“很不满意”,而后台修改错误的工作量越来越大,不得已才查看帮助、参考文档进行修改。

后续工作:

  1. 补充知识 JS(JQuery, Ajax),https://api.jquery.com/jquery.ajax/ -- 估计还要看使用者反馈,要不要偷懒;
  2. 页面出错或刷新后project/task如何响应,扩展哪个block;

知识扩展:模版继承  -- 待续

  1. {% extends “template_name” %}
    {% extends "base.html"%}     -- extend parent template
    {% block title %}            -- extend block
    
    {{ block.super }}            -- override or overwrite or cover parent template  
     
    {% endblock %}               -- end extend

     

  2. {% include “template_name” %}  
    包含另一模板