Vue-dvadmin-d2-crud-plus-自定义后台菜单-添加页面

news2024/11/16 19:32:55

文章目录

    • 1.新建数据模型
    • 2.新建数据序列类
    • 3.新建数据视图
    • 4.配置路由
    • 5.前端新建View组件
    • 6.配置后台
    • 7.总结

django-vue-admin是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
🧑‍🤝‍🧑前端采用D2Admin 、Vue、ElementUI。
👭后端采用 Python 语言 Django 框架以及强大的 Django REST Framework。
👫权限认证使用Django REST Framework SimpleJWT,支持多终端认证系统。
👬支持加载动态权限菜单,多方式轻松权限控制。
💏特别鸣谢:D2Admin 、Vue-Element-Admin。
在这里插入图片描述
这套系统需要Django的基础知识,REST Framework框架的基础理解以及D2Admin的基础理解。本文从头开始简易说明如何用dvadmin管理一张数据表。

1.新建数据模型

处理数据是计算机最初开始的地方。在Django中,称为数据模型。声明如下:

class UserIPStatistics(CoreModel):#CoreModel 是dvadmin的核心字段,含用户信息
    ip = models.CharField(max_length=255, verbose_name='IP', help_text="IP")
    num = models.IntegerField( verbose_name='完成次数', help_text="完成次数", blank=True, default=0)

    class Meta:
        db_table = table_prefix + "UserStatistics"
        verbose_name = '用户使用次数'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)

2.新建数据序列类

将用户ID转为用户名,方便在前端显示。

#用户统计序列化
class UserIPStatisticsSerializer(serializers.ModelSerializer):
    #自定义字段
    creator = serializers.SerializerMethodField();
    zl_user=serializers.CharField(source="creator");#自定义字段

    #转为用户名
    def get_creator(self, obj):
        try:
            rlt=obj.creator.username;
            return rlt;
        except Exception as e:
            return ""

    class Meta:
        model = UserIPStatistics
        fields = '__all__'
        read_only_fields = ('id', 'zl_user')

3.新建数据视图

指明查询集,序列化类和权限验证类。与文章开始的图保持一致。

# IP统计数据
class UserIPStatisticsViewSet(viewsets.ModelViewSet):
    queryset = UserIPStatistics.objects.all()
    serializer_class = UserIPStatisticsSerializer
    permission_classes = (permissions.IsAuthenticated,)

4.配置路由

如果在应用中,需要将应用的路由包含到Project中urls中,这里假设读者具备这方面的基础知识。

router = routers.SimpleRouter()
router.register(r'useripstatistics', UserIPStatisticsViewSet)

urlpatterns += router.urls
urlpatterns = format_suffix_patterns(urlpatterns)

注意:模型数据一般放在models文件中,序列类可以放在views文件中,也可以放在单独的serializers文件中,数据视图类放在views文件中。

执行以下命令进行数据的迁移。

python.exe manage.py makemigrations
python.exe manage.py migrate
python.exe manage.py init

---------------------------------------------------------至此,后台配置完成-------------------------------------------------------

5.前端新建View组件

在src/views目标下新建UserIPStatistics文件夹,并新建api.js + crud.js +index.vue 三个文件。
在这里插入图片描述
api.js文件内容:

import { request } from '@/api/service' //系统封装好的请求后端数据

export const urlPrefix = '/colorlabel/useripstatistics/' //该组件访问的后端restful接口

/**
 * 列表查询
 */
export function GetList (query) {
  query.limit = 999
  return request({
    url: urlPrefix,
    method: 'get',
    params: query
  })
}

/**
 * 新增
 */
export function createObj (obj) {
  return request({
    url: urlPrefix,
    method: 'post',
    data: obj
  })
}

/**
 * 修改
 */
export function UpdateObj (obj) {
  return request({
    url: urlPrefix + obj.id + '/',
    method: 'put',
    data: obj
  })
}

/**
 * 删除
 */
export function DelObj (id) {
  return request({
    url: urlPrefix + id + '/',
    method: 'delete',
    data: { id }
  })
}

crud.js文件内容:
主要是表格显示参数的配置。

// eslint-disable-next-line no-unused-vars
// import { request } from '@/api/service'
// eslint-disable-next-line no-unused-vars
// import { BUTTON_STATUS_NUMBER } from '@/config/button'
// eslint-disable-next-line no-unused-vars
// import { urlPrefix as bookPrefix } from './api'

export const crudOptions = (vm) => {
  return {
    pageOptions: {
      compact: true
    },
    options: {
      tableType: 'vxe-table',
      rowKey: true, // 必须设置,true or false
      rowId: 'id',
      height: '100%', // 表格高度100%, 使用toolbar必须设置
      highlightCurrentRow: false
    },
    rowHandle: {//操作按钮行的配置
      width: 140,
      view: {
        thin: true,
        text: '',
        disabled () {
          return !vm.hasPermissions('Retrieve')
        }
      },
      edit: {
        thin: true,
        text: '',
        disabled () {
          return false
          //return !vm.hasPermissions('Update')
        },
        show: false
      },
      remove: {
        thin: true,
        text: '',
        hidden: true,
        disabled () {
          return false
          //return !vm.hasPermissions('Delete')
        },
        show: false
      }
    },
    indexRow: { // 或者直接传true,不显示title,不居中
      title: '序号',
      align: 'center',
      width: 100
    },
    viewOptions: {
      componentType: 'form'
    },
    formOptions: {
      defaultSpan: 24, // 默认的表单 span
      width: '35%'
    },
    columns: [{//每一列的字段指定
      title: '关键词',
      key: 'search',
      show: false,
      disabled: true,
      search: {
        disabled: false
      },
      form: {
        disabled: true,
        component: {
          props: {
            clearable: true
          },
          placeholder: '请输入关键词'
        }
      },
      view: { // 查看对话框组件的单独配置
        disabled: true
      }
    },
    {
      title: 'ID',
      key: 'id',//与返回json数据的key对应
      show: false,
      disabled: true,
      width: 90,
      form: {
        disabled: true
      }
    },
    {
      title: '用户名',
      key: 'creator',
      sortable: true,
      treeNode: true,
      search: {
        disabled: false,
        component: {
          props: {
            clearable: true
          }
        }
      },
      type: 'input',
      form: {
        editDisabled: true,
        rules: [ // 表单校验规则
          { required: true, message: '编码必填项' }
        ],
        component: {
          props: {
            clearable: true
          },
          placeholder: '请输入编码'
        },
        itemProps: {
          class: { yxtInput: true }
        }
      }
    },
    {
      title: 'IP',
      key: 'ip',
      sortable: true,
      treeNode: true,
      search: {
        disabled: false,
        component: {
          props: {
            clearable: true
          }
        }
      },
      type: 'input',
      form: {
        editDisabled: true,
        rules: [ // 表单校验规则
          { required: true, message: '编码必填项' }
        ],
        component: {
          props: {
            clearable: true
          },
          placeholder: '请输入编码'
        },
        itemProps: {
          class: { yxtInput: true }
        }
      }
    },
    {
      title: '次数',
      key: 'num',
      sortable: true,

      search: {
        disabled: false,
        component: {
          props: {
            clearable: true
          }
        }
      },

      type: 'number',
      form: {
        rules: [ // 表单校验规则
          { required: true, message: '显示值必填项' }
        ],
        component: {
          props: {
            clearable: true
          },
          placeholder: '请输入显示值'
        },
        itemProps: {
          class: { yxtInput: true }
        }
      }
    }
    ]//.concat(vm.commonEndColumns())
  }
}

index.vue 文件内容:

<template>
  <d2-container :class="{ 'page-compact': crud.pageOptions.compact }">
    <d2-crud-x ref="d2Crud" v-bind="_crudProps" v-on="_crudListeners">
      <div slot="header">
        <crud-search ref="search" :options="crud.searchOptions" @submit="handleSearch" />
        <crud-toolbar :search.sync="crud.searchOptions.show" :compact.sync="crud.pageOptions.compact" :columns="crud.columns" @refresh="doRefresh()" @columns-filter-changed="handleColumnsFilterChanged"/>
      </div>
    </d2-crud-x>
  </d2-container>
</template>

<script>
import * as api from './api'
import { crudOptions } from './crud'
import { d2CrudPlus } from 'd2-crud-plus'

export default {
  name: 'useripstatistics',
  mixins: [d2CrudPlus.crud],
  data () {
    return {}
  },
  methods: {
    getCrudOptions () {
      return crudOptions(this)
    },
    pageRequest (query) {
      return api.GetList(query)
    },
    /*addRequest (row) {
      d2CrudPlus.util.dict.clear()
      return api.createObj(row)
    },
    updateRequest (row) {
      d2CrudPlus.util.dict.clear()
      return api.UpdateObj(row)
    },
    delRequest (row) {
      return api.DelObj(row.id)
    },*/
    // 授权
    createPermission (scope) {
      this.$router.push({
        name: 'menuButton',
        params: { id: scope.row.id },
        query: { name: scope.row.name }
      })
    }
  }
}
</script>

<style lang="scss">
  .yxtInput {
    .el-form-item__label {
      color: #49a1ff;
    }
  }
</style>

注意如果是上传文件,应该使用file-uploader类型。并在valueResolve (row, key) 方法中修改值为文件名,否则报错。

valueBuilder (row, key)//在返回之后,填入界面之前进行
{
    // 某些组件传入的value值可能是一个复杂对象,而row中的单个属性的值不合适传入
    // 则需要在打开编辑对话框前将row里面多个字段组合成组件需要的value对象
    // 例如:国际手机号(mobileValue为此column的key)
    // 示例 http://preview.d2-crud-plus.docmirror.cn/D2CrudPlusExample/#/demo/form/phone
    // row.mobileValue = { phoneNumber: row.phone, callingCode: row.code, countryCode: row.country }
    // valueBuilder将会在pageRequest成功返回数据后执行
},
valueResolve (row, key)//在上传序列化之前进行
{
    // 组件中传回的值也需要分解成row中多个字段的值,用于提交给后台。
    // 例如:
    // if (row.mobileValue != null) {
    //  row.phone = row.mobileValue.phoneNumber
    //  row.code = row.mobileValue.callingCode
    //  row.country = row.mobileValue.countryCode
    // }
    // valueResolve 将会在
    //   addRequest(解析添加表单的值)
    //   updateRequest(解析编辑表单的值)
    //   pageRequest(解析查询参数)
    // 之前执行
}

6.配置后台

添加菜单,配置如下,需要改成自己的配置。
在这里插入图片描述
配置访问方式
在这里插入图片描述
点击按钮配置,按restful api方式添加增删查改的路由路径。
在这里插入图片描述
在这里插入图片描述
刷新以下后台,菜单界面就是显示出来最终结果:
在这里插入图片描述

7.总结

dvadmin 能够以简易快捷的方式构建一套后台管理系统,能够快速进行后台表格的管理,十分友好便捷,缺点就是文档,不是很全面,遇到bug需要自己诊断一下源码,找出问题所在。

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

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

相关文章

搭建nuxt3项目(框架构建)

需求 目标&#xff1a;我想搭建一个nuxt3的框架&#xff0c;实现一些基本的组件和路由、页面&#xff0c;方便后续遇到相关ssr项目直接复用。 同时&#xff1a;记录关于nuxt3的使用介绍关于Nuxt&#xff08;详解以及周边&#xff09; Nuxt 框架 1、一种基于 Node.js 的服务端…

Java-多线程进阶

文章目录 Java多线程进阶锁的类型乐观锁vs悲观锁读写锁重量级锁vs轻量级锁自旋锁公平锁vs非公平锁可重入锁vs不可重入锁 CASCAS介绍和原理CAS应用自旋锁CAS 的 ABA 问题 Synchronized 原理Callable 接口JUC常见类ReentrantLock原子类线程池信号量 SemaphoreCountDownLatch 线程…

Unity之ShaderGraph如何实现旋涡效果

前言 今天我们来通过ShaderGraph来实现一个旋涡的效果 如下图所示&#xff1a; 主要节点 Distance&#xff1a;返回输入 A 和输入 B 的值之间的欧几里德距离。除了其他方面的用途&#xff0c;这对于计算空间中两点之间的距离很有用&#xff0c;通常用于计算有符号距离函数 (…

JAVA基础(JAVA SE)学习笔记(八)面向对象编程(高级)

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 第二阶段&#xff1a;Java面向对象编程 6.面向对象编程&#xff08;基础&#xff09; 7.面向对象编程&…

C++标准模板(STL)- 类型支持 (类型特性,is_void,is_null_pointer,is_integral)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实…

【小呆的概率论学习笔记】抽样调查之用抽样样本估计母体数字特征

文章目录 1. 随机变量的数字特征1.1 随机变量的均值&#xff08;期望&#xff09;1.2 随机变量的方差1.3 随机变量的协方差 2. 抽样调查3. 用抽样样本估计母体数字特征3.1 估计母体样本均值3.2 抽样样本均值的方差3.2 估计母体样本方差 1. 随机变量的数字特征 随机变量本质上是…

手把手教你在项目中引入Excel报表组件

摘要&#xff1a;本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 GrapeCity Documents for Excel&#xff08;以下简称GcExcel&#xff09;是葡萄城公司的…

《VS2013+ Qt5.6 创建Qt对话框(*.ui 文件, *.h, *.cpp )》

标题&#xff1a;如何在Visual Studio 2013中创建Qt对话框项目 简介 在本篇博客中&#xff0c;我们将介绍如何使用Visual Studio 2013和Qt 5.6创建一个Qt对话框项目&#xff0c;包括创建.ui文件、.h文件和.cpp文件&#xff0c;以及构建一个基本的用户界面和业务逻辑。&#x…

自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例

自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例 在matlab中有自带的离散傅里叶变换程序&#xff0c;即fft程序&#xff0c;但该程序是封装的&#xff0c;无法看到源码。为了比较清楚的了解matlab自带的实现过程&#xff0c;本文通过自建程序实现matlab程序&…

DenseNet 和 FractalNet学习笔记

文章目录 网络结构模型细节下采样增长率 代码实现FractalNet 模型(2016) 网络结构 假设输入为一个图片X0&#xff0c;经过一个L层的神经网络&#xff0c;第l层的特征输出记作Xl&#xff0c;那么残差连接的公式如下所示&#xff1a; x l H l ( X l − 1 ) X l − 1 x_lH_l(X…

【光电子技术+光纤通信】博资考

光电子技术与光纤通信基础总结 几何光学波动光学光电子器件激光器光调制器光探测器光纤 几何光学 折射率是比值定义式&#xff0c;定义为入射介质光速比上折射介质光速&#xff0c;它与optical density意义相似&#xff0c;可以表示传播介质对于光传播的阻碍程度&#xff0c;因…

Postman的简单使用

Postman简介 官网 Postman是Google公司开发的一款功能强大的网页调试与发送HTTP请求&#xff0c;并能运行测试用例的Chrome插件 使用Postman进行简单接口测试 新建测试 → 选择请求方式 → 请求URL&#xff0c;下面用百度作为例子&#xff1a; 参考文档 [1] Postman使用教程…

AIR101 LuatOS LVGL 显示多个标签例程

屏幕资料 AIR101与屏幕连接 PC端仿真环境合宙官方PC端版本环境搭建教程 PC电脑仿真 -- sys库是标配 _G.sys require("sys") sys.taskInit(function()local cnt0lvgl.init(480,320)--lvgl初始化local cont lvgl.cont_create(nil, nil);-- lvgl.cont_set_fit(cont, …

cocosCreator 之 dispatchEvent事件分发

版本&#xff1a; 3.8.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac Node事件派发 cocosCreator支持使用Node节点进行事件派发(dispatchEvent)&#xff0c;事件派发系统是按照 Web 的事件冒泡及捕获标准 实现的。 事件派发主要通过冒泡的方式逐渐向父节点传递。 在派…

整数智能·迪拜GITEX 2023 |探索未来科技,感受创新脉搏

第43届GITEX GLOBAL在迪拜世界贸易中心盛大开幕&#xff0c;聚集来自全球各地的6000多家参展企业&#xff0c;包含大量来自于人工智能、区块链、网络安全、可持续技术等领域的科技巨头和革命性初创企业&#xff0c;展示全球科技最新趋势和创新机遇。GITEX GLOBAL始办于1981年&a…

OpenText 安全取证软件——降低成本和风险的同时,简化电子取证流程

OpenText 安全取证软件&#xff0c;行业标准的数字调查解决方案&#xff0c;适用于各种规模和各种行业的组织 降低成本和复杂性 • 远程调查比轮流调查过程更有效 对结果持有信心 • 磁盘级可见性可以完成相关端点数据的搜索和收集 谨慎调查 • 完整的网络调查&#xf…

Linux常用文件和目录管理

本文旨在对y总的Linux基础课做学习记录&#xff0c;方便日后复习 参考视频&#xff1a;Linux基础课 参考教程&#xff1a;Linux教程 0 绝对路径和相对路径 Linux 的目录结构为树状结构 绝对路径&#xff1a;由根目录 / 写起&#xff0c;例如&#xff1a; /usr/share/doc相对…

华为云2023年双十一服务器优惠价格表及活动大全

2023华为云双11优惠活动「云上优选 特惠来袭」&#xff0c;阿腾云atengyun.com整理云服务器优惠价格表&#xff0c;华为云L实例-2核2G3M一年优惠价89元、L实例-2核2G4M价格108元一年、L实例-2核4G5M优惠价198元一年&#xff0c;三年1000元、HECS云服务器-1核2G1M带宽39元一年、…

【C++】继承和多态

继承和多态 一、继承1. 继承概念2. 继承定义&#xff08;1&#xff09;继承的格式定义&#xff08;2&#xff09;继承父类成员访问方式的变化 3. 父类和子类对象赋值转换4. 继承中的作用域5. 子类的默认成员函数6. 继承与友元7. 继承与静态成员8. 复杂的菱形继承及菱形虚拟继承…

Zynq UltraScale+ XCZU9EG 纯VHDL解码 IMX214 MIPI 视频,2路视频拼接输出,提供vivado工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 MIPI 编解码方案3、本 MIPI CSI2 模块性能及其优越性4、详细设计方案设计原理框图IMX214 摄像头及其配置D-PHY 模块CSI-2-RX 模块Bayer转RGB模块伽马矫正模块VDMA图像缓存Video Scaler 图像缓存DP 输出 5、vivado工程详解PL端FPGA硬件设计…