Python入门自学进阶-Web框架——24、DjangoAdmin项目应用-定制页面2

news2024/10/6 0:30:07

这里要实现点击对应的表名称,显示具体表的详细内容,大致的流程是:

前端显示各个表名,如下:

<tbody>
                    {% for  table_name,admin in app_tables.items %}
                    <tr class="border-bottom">
                      <td style="padding-bottom: 3px;padding-top: 3px;">
                          <a href="{% url 'table_objs' app_name table_name %}">{% render_app_name admin %}</a>
                      </td>
                      <td style="padding-bottom: 3px;padding-top: 3px;">Add</td>
                      <td style="padding-bottom: 3px;padding-top: 3px;">Change</td>
                    </tr>
                    {% endfor %}
</tbody>

主要就是:<a href="{% url 'table_objs' app_name table_name %}">{% render_app_name admin %}</a>,

对应表名的url被解析成/应用名/表名,如/plcrm/customer形式,对应的在路由项中有如下路由:path('<str:app_name>/<str:table_name>/',views.display_table_objs,name="table_objs"),请求处理的函数是views.display_table_objs:

def display_table_objs(req,app_name,table_name):
    print("====>",app_name,table_name)
   
    admin_class = mytestapp_admin.enable_admins[app_name][table_name]

    print('-----.....>',admin_class,admin_class.model.__name__)

    return render(req,"mytestapp/table_objs.html",{"admin_class":admin_class})

通过enable_admins字典获取到对应的admin_class,然后传递到前端,即table_objs.html,然后在全端展示各字段:

<!-- 表体中按照表头的字段,循环显示表中的数据 -->
              <!-- 因为函数传递的是admin_class,而admin_class中有model属性,保存了对应的model类,感觉可以直接如下取数显示-->
                {% for columndata in admin_class.model.objects.all %}
                    <tr>
                        <td>{{ columndata }}</td>
                    </tr>
                {% endfor %}

上面的代码运行时会出现错误:

 在网上查询,一般是这样解释的:出现这种错误是因为调用模型对象时使用了变量名,而不是对象名(模型类),也就是说必须使用对象名,如这里应该是Customer,但是后台传递过来的,即视图函数中带的数据就一个admin_class,这里就是CustomerAdmin,以通常的理解,CustomerAdmin中有model属相,这个属性的值是Customer,那就应该可以的,实际不行。

也就是说,在模板中使用models类取数时,必须使用类名称,不能使用变量名。所以,要使用Customer类来取对应表中的数据,但是视图函数要传递数据给模板,是用的字典,也就是模板使用的是key,无法使用类名,从而也就无法直接在模板中使用model类直接取数,需要在视图函数中查询出数据,传递给模板,或者在模板中使用自定义标签,来完成取数的功能。

第一种:修改视图函数,在视图函数中获取数据,然后传递给模板:

def display_table_objs(req,app_name,table_name):
    
    admin_class = mytestapp_admin.enable_admins[app_name][table_name]
    models_data = admin_class.model.objects.all()
    return render(req,"mytestapp/table_objs.html",{"admin_class":admin_class,"model_class_name":admin_class.model.__name__,'model_data':models_data})

传给模板的model_data是查询出的数据QuerySet型数据,在模板中:

 {% for kk in model_data %}
         <tr>
                <td>{{ kk.name }} | {{ kk.qq }}</td>
         </tr>
{% endfor %}

因为前端显示的是admin_class中的list_display中定义的字段,所以,修改一下视图函数的中取数:models_data = admin_class.model.objects.values_list(*admin_class.list_display)

前端:

 {% for kk in model_data %}
      <tr>
          {% for gg in kk %}
               <td>{{ gg }} </td>
          {% endfor %}
      </tr>
{% endfor %}

第二种,使用自定义标签,也可以有两种处理方法

1、标签可以按照admin_class中的list_display取数,传递给前端,前端遍历生成html

@register.simple_tag
def get_query_sets_1(admin_class):
    return admin_class.model.objects.values_list(*admin_class.list_display)

前端循环:

<tbody>
       {% get_query_sets_1 admin_class as query_sets %}
       {% for obj in query_sets %}
             <tr>
                  {% for obj_item in obj %}
                      <td colspan="6">{{ obj_item }}</td>
                  {% endfor %}
              </tr>
       {% endfor %}
</tbody>

2、标签返回model中全部数据,再定义一个标签,按照list_display组装这些数据,生成一个html字符串,传递个前端。

@register.simple_tag
def get_query_sets_1(admin_class):
    return admin_class.model.objects.all()


@register.simple_tag
def build_table_row(obj,admin_class):
    row_ele = ""
    for row_data in obj:
        row_ele = row_ele +"<tr>"
        for column in admin_class.list_display:
            column_data = getattr(row_data,column)
            row_ele += "<td colspan='6'>%s</td>"%column_data
        row_ele = row_ele + "</tr>"
    return mark_safe(row_ele)

前端:

<tbody>
                {% get_query_sets_1 admin_class as query_sets %}
                {% build_table_row query_sets admin_class %}

</tbody>

这种方法有一个问题,对于tags,使用getattr()取出的是plcrm.Tag.None,而使用第一种和视图函数返回,都是数值。

还有一个共同的问题,就是model类中有choices项的,对应的应该显示choices中的值,如source,这里都是显示数字,正常,显示说明文字,即对应的choices中的说明。

只能使用自定义标签方法的第二种:在组装标签时判断与替换

@register.simple_tag
def build_table_row(obj,admin_class):
    row_ele = ""
    print("===///:::",obj)
    for row_data in obj:
        row_ele = row_ele +"<tr>"
        for column in admin_class.list_display:
            field_obj = row_data._meta.get_field(column)
            if field_obj.choices:
                column_data = getattr(row_data,"get_%s_display"%column)()
            else:
                column_data = getattr(row_data,column)
            row_ele += "<td colspan='6'>%s</td>"%column_data
        row_ele = row_ele + "</tr>"
    print(row_ele)
    return mark_safe(row_ele)

显示如下:

 

 source字段显示正确了,但是tags不正确,tags是manytomany的外键,修改一下:

@register.simple_tag
def build_table_row(obj,admin_class):
    row_ele = ""
    print("===///:::",obj)
    for row_data in obj:
        row_ele = row_ele +"<tr>"
        for column in admin_class.list_display:
            field_obj = row_data._meta.get_field(column)
            if field_obj.choices:
                column_data = getattr(row_data,"get_%s_display"%column)()
            else:
                column_data = getattr(row_data,column)
            field_obj1 = getattr(row_data,column)
            if hasattr(field_obj1,'values'):
                s = ""
                dic1 = field_obj1.values()[0]
                print(type(dic1),dic1)
                for v in dic1.values():
                    s = s + str(v) + ';'
                column_data = s

            row_ele += "<td colspan='6'>%s</td>"%column_data
        row_ele = row_ele + "</tr>"
    print(row_ele)
    return mark_safe(row_ele)

对于外键,主要是判断字段是否有values方法(注意跟遍历字典时的values区别)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1712.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

彻底理解Java并发:volatile关键字

本篇内容包括&#xff1a;volatile 关键字简介、volatile 保证可见性&#xff08;包括&#xff1a;关乎不可见性问题描述、JMM内存模型和不可见性的解决方案&#xff09;以及 volatile 其他特性&#xff08;包括&#xff1a;volatile 不保证原子性、volatile 原子性的保证操作、…

mysql-高级命令(1)和一些函数(悟已往之不谏,知来者之可追)

一、高级命令 1.查询某个字段和多个字段 select 某个字段&#xff08;或者多个字段&#xff0c;中间以逗号间隔&#xff09;from 表名&#xff1b; 2. 去除字段的重复值 3.and 表示&#xff08;两个条件都需要满足&#xff09; 4.or &#xff08;两个条件满足一点&#xff09;…

【Linux】软件包管理器 yum 与编辑器 vim 的基本使用

文章目录一、yum 背景知识1、商业生态2、开源生态3、软件生态本土化二、yum 的基本使用1、查看软件包2、安装软件3、卸载软件三、vim 的基本使用1、vim 的基本概念2、vim 的基本操作2.1 模式间切换2.2 光标定位2.3 文本复制2.4 文本编辑2.5 底行模式的操作四、简单 vim 配置2、…

SpringBoot+SpringCloud+Nutty打造分布式在线消息推送服务(实例)

文章目录前言技术架构效果图后端项目消息数据定义存储结构消息状态Nutty消息服务项目结构改动消息bean消息处理器消息转换pojo工具审核消息处理controller实现类服务调用前端连接代码初始化接受消息消息的展示效果总结前言 其实关于这个的话&#xff0c;我先前的几篇博文&…

css选择器

碎碎念&#xff1a;都是一些自己在学习过程中的一点体会&#xff0c;如果有什么不对的感谢大家指正一起学习&#xff01; css选择器一、常用选择器二、属性选择器三、其他五、栗子1. * 通配符2. 空格 div p3. > 子选择器4. ~ 通用兄弟选择器5. 相邻兄弟选择器6. , 选择器分…

使用 Vercel 快速部署前端项目

Vercel&#xff1a;一键部署前端项目。 前端项目部署的问题 先来说下前端项目的部署&#xff0c;一般来说有以下几个步骤&#xff1a; 项目打包上传到服务器域名解析SSL 证书申请Nginx 配置CDN 加速 如果是公司的项目&#xff0c;打包之后的步骤一般有专门的运维人员负责&am…

C++:多态

文章目录一、多态的概念二、多态的定义及实现2.1 多态的构成条件2.2 虚函数2.3 虚函数的重写(覆盖)2.4 override 和 final2.5 重载、覆盖(重写)、隐藏(重定义)的对比三、抽象类四、继承和多态常见的面试问题1.2.总结一、多态的概念 多态按字面的意思就是多种形态。当类之间存在…

瞪羚优化算法(Gazelle Optimization Algorithm,GOA)

瞪羚优化算法&#xff08;Gazelle Optimization Algorithm&#xff0c;GOA&#xff09;由Agushaka等人于2022年提出&#xff0c;该算法模拟了瞪羚逃避捕食者的行为&#xff0c;思路新颖&#xff0c;性能高效。 瞪羚的身高60-110厘米&#xff0c;体重13-29千克。该属物种有像小鹿…

【Linux】基本指令(上)

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;操作系统&…

Linux - 第2节 - Linux环境基础开发工具使用

1.Linux 软件包管理器 yum centos 7中安装软件的方式&#xff1a; &#xff08;1&#xff09;源码安装 &#xff08;2&#xff09;rpm包安装 &#xff08;3&#xff09;yum安装 yum安装的好处&#xff1a; &#xff08;1&#xff09;不用编译源码 &#xff08;2&#xff09;不用…

赶紧进来看看---C语言实现学生信息管理系统(2.0动态内存版)

本文介绍了将学生信息管理系统静态版本改造为动态内存版本,主要涉及改造思路,枚举类型的使用,动态内存函数和柔性数组的使用,动手写程序才能使基础知识更为牢固…(文章最后有源码展示) 学生信息管理系统1.0静态版->学生信息管理系统2.0动态内存版 c语言实现学生信息管理系统…

在python中使用ggplot2

python的ggplot2库:plotnine > 一.安装方法&#xff1a; pip install plotnine使用的编译器&#xff1a;pycharm 二.plotnine绘图 1.第一个图形 除了导包的操作不一致&#xff0c;其他类似 from plotnine import ggplot, geom_point, aes, stat_smooth, facet_wrap fr…

70.【JavaScript 6.0】

前端三要素1.前端三要素2.引入JavaScript3.JavaScript基本语法入门4.数据类型5.严格检查模式( use strict)6.Map和Set7.函数的定义和参数获取8.变量的作用域(局部 全局)-------> 和Java一样9.全局规范:10.方法的定义和调用11.内部对象1.Date--------->日期2.JSON--------…

自定义mybatis插件实现sql日志打印

自定义mybatis插件实现sql日志打印 mysql插件实现原理 官网的关键信息 参考文档 https://mybatis.org/mybatis-3/zh/configuration.html#plugins 官方文档 MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下&#xff0c;MyBatis 允许使用插件来拦截的方…

【JavaSE】一篇文章领悟Java运算符

前言&#xff1a; 作者简介&#xff1a;爱吃大白菜1132 人生格言:纸上得来终觉浅&#xff0c;绝知此事要躬行 如果文章知识点有错误的地方不吝赐教&#xff0c;和大家一起学习&#xff0c;一起进步&#xff01; 如果觉得博主文章还不错的话&#xff0c;希望三连支持&#xff01…

Java项目:超市管理系统(java+SSM+JSP+LayUI+jQ+Mysql)

源码获取&#xff1a;俺的博客首页 "资源" 里下载&#xff01; 项目介绍 本项目分为超级管理员、总经理、店长、员工等角色&#xff0c;超级管理员可添加修改删除角色并进行角色菜单配置&#xff1b; 超级管理员角色包含以下功能&#xff1a; 商品管理&#xff1a;添…

C语言高级-4栈

14天阅读挑战赛 目录 一、栈的原理 1、栈的定义 2、栈的应用 &#xff08;1&#xff09;选课问题 &#xff08;2&#xff09;旅游&#xff1a;怎么样把每个城市去且仅去一遍&#xff1f; &#xff08;3&#xff09;栈的使用场景 &#xff08;4&#xff09;思考&#xf…

C++多态之虚函数表详解及代码示例

引言 C相对其他面向对象语言来说&#xff0c;之所以灵活、高效。很大程度的占比在于其多态技术和模板技术。C虚函数表是支撑C多态的重要技术&#xff0c;它是C动态绑定技术的核心。 如果对多态还不了解的小伙伴&#xff0c;可以点这里C多态详解基础篇。 在不考虑继承的情况下…

Vue3 Hooks 模块化抽离

Vue3中的Hooks 其实就是业务逻辑的抽离&#xff0c;跟Vue2中mixin 本质上是一样的&#xff1a;将当前组件的业务逻辑抽离到一个公共的文件中&#xff0c;提高逻辑复用性&#xff0c;让当前组件看起来更加清爽&#xff0c;不太一样的地方是我们封装hooks 的时候一般是返回一个函…

如何不改动 GatewayWorker 依赖包下自定义协议

前言&#xff1a; GatewayWorker 是 Workerman 的一个框架&#xff0c;对应用层开发者更友好。GatewayWorker 多了一个网关&#xff0c;也就是 Gateway&#xff0c;负责与客户端连接&#xff0c;消息转发等。而自定义的协议&#xff0c;也就是 gateway 面向客户端提供服务的协议…