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

文章目录

    • 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需要自己诊断一下源码,找出问题所在。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

calcite 校验层总结

1、校验的作用 1&#xff09;完善语义信息 例如在SQL语句中&#xff0c;如果碰到select * 这样的指令&#xff0c;在SQL的语义当中&#xff0c;“*” 指的是取出对应数据源中所有字段的信息&#xff0c;因此就需要根据元数据信息来展开。 2&#xff09;结合元数据信息来纠偏…

分享一下怎么做陪诊小程序

在当今快节奏的社会中&#xff0c;人们的生活压力越来越大&#xff0c;尤其是在大城市中&#xff0c;由于工作繁忙&#xff0c;生活节奏快&#xff0c;很多人都感到看病难、看病贵的问题。为了解决这一问题&#xff0c;陪诊小程序应运而生。陪诊小程序是一种可以提供线上预约、…

世界前沿技术发展报告2023《世界航空技术发展报告》(四)无人机技术

&#xff08;四&#xff09;无人机技术 1.无人作战飞机1.1 美国空军披露可与下一代战斗机编组作战的协同式无人作战飞机项目1.2 俄罗斯无人作战飞机取得重要进展 2.支援保障无人机2.1 欧洲无人机项目通过首个里程碑2.2 美国海军继续开展MQ-25无人加油机测试工作 3.微小型无人机…

shell脚本的编写(输入、输出、变量、数组等的使用规范及实例)

1.shell中变量的定义 使用变量的值&#xff1a; 例子&#xff1a; 2.外部传参/位置变量 例子&#xff1a; 3.输出---echo 4.输入---read 5.命令置换符 作用:把指令的运行结果赋值给变量 6.数组--shell支持稀疏数组

threejs(7)-精通粒子特效

一、初识Points与点材质 // 设置点材质 const pointsMaterial new THREE.PointsMaterial(); import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 导入动画库 import gsa…

华为NAT配置实例(含dhcp、ospf配置)

一、网络拓朴如下&#xff1a; 二、要求&#xff1a;PC1 能访问到Server1 三、思路&#xff1a; R2配置DHCP&#xff0c;R2和R1配OSPF&#xff0c;R1出NAT 四、主要配置&#xff1a; R2的DHCP和OSPF&#xff1a; ip pool 1gateway-list 10.1.1.1 network 10.1.1.0 mask 25…

面试算法40:矩阵中的最大矩形

题目 请在一个由0、1组成的矩阵中找出最大的只包含1的矩形并输出它的面积。例如&#xff0c;在图6.6的矩阵中&#xff0c;最大的只包含1的矩阵如阴影部分所示&#xff0c;它的面积是6。 分析 直方图是由排列在同一基线上的相邻柱子组成的图形。由于题目要求矩形中只包含数字…

python3+requests+unittest实战详解(一)

1、环境准备 python3 pycharm编辑器 2、框架目录展示 &#xff08;该套代码只是简单入门&#xff0c;有兴趣的可以不断后期完善&#xff09; &#xff08;1&#xff09;run.py主运行文件&#xff0c;运行之后可以生成相应的测试报告&#xff0c;并以邮件形式发送&#xff1…

什么是web3.0?

Web 3.0&#xff0c;也常被称为下一代互联网&#xff0c;代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识&#xff0c;但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念&#xff1a; 1. 去中心化 Web 3.0旨在减少…

vue3学习(十四)--- vue3中css新特性

文章目录 样式穿透:deep()scoped的原理 插槽选择器:slotted()全局选择器:global()动态绑定CSScss module 样式穿透:deep() 主要是用于修改很多vue常用的组件库&#xff08;element, vant, AntDesigin&#xff09;&#xff0c;虽然配好了样式但是还是需要更改其他的样式就需要用…

在类库中使用ASP.NET Core API

解决办法1 官方文档 解决办法2 将类库修改为web项目&#xff0c;然后设置输出为类库形式即可 <Project Sdk"Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework><OutputType>Library</O…

Wpf 使用 Prism 实战开发Day02

一.设计首页导航条 导航条的样式&#xff0c;主要是从Material DesignThemes UI 拷贝过来修改的,项目用了这个UI组件库&#xff0c;就看自己需要什么&#xff0c;就去拷过来使用&#xff0c;界面布局或其他组件使用&#xff0c;不做介绍。 直接下载源码&#xff0c;编译运行就可…

初识Node.js开发

一、Node.js是什么 1.node.js是什么 官方对Node.js的定义&#xff1a; Node.js是一个基于V8 JavaScript引擎的JavaScript运行时环境。 也就是说Node.js基于V8引擎来执行JavaScript的代码&#xff0c;但是不仅仅只有V8引擎&#xff1a; 前面我们知道V8可以嵌入到任何C 应用…

《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码

在注意力机制中&#xff0c;每个查询都会关注所有的键&#xff0d;值对并生成一个注意力输出。由于查询、键和值来自同一组输入&#xff0c;因此被称为 自注意力&#xff08;self-attention&#xff09;&#xff0c;也被称为内部注意力&#xff08;intra-attention&#xff09;…

图纸管理制度 《五》

1、存档文件应由专人管理&#xff0c;其他人未征得管理人员同意&#xff0c;不得随意翻阅查看。 2、档案管理人员要认真贯彻执行公司相关制度&#xff0c;严禁泄露档案材料中的秘密。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件…

docker 部署 若依 Ruoyi springboot+vue分离版 dockerCompose

本篇从已有虚拟机/服务器 安装好dokcer为基础开始讲解 1.部署mysql 创建conf data init三个文件夹 conf目录存放在mysql配置文件 init目录存放着若依数据库sql文件&#xff08;从navicat导出的并非若依框架自带sql&#xff09; 创建一个属于本次若依部署的网段&#xff08;只…

【产品经理】APP备案(阿里云)

工信部《关于开展移动互联网应用程序备案工作的通知》 工业和信息化部印发了《关于开展移动互联网应用程序备案工作的通知》&#xff0c;“在中华人民共和国境内从事互联网信息服务的App主办者&#xff0c;应当依照相关法律法规等规定履行备案手续&#xff0c;未履行备案手续的…

【C程序设计】用心浇灌<C程序>

目录 数据类型 整数类型 实例 浮点类型 void 类型 类型转换 数据类型 在 C 语言中&#xff0c;数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间&#xff0c;以及如何解释存储的位模式。 C 中的类型可分为以下几种&…

深度学习使用Keras进行迁移学习提升网络性能

上一篇文章我们用自己定义的模型来解决了二分类问题,在20个回合的训练之后得到了大约74%的准确率,一方面是我们的epoch太小的原因,另外一方面也是由于模型太简单,结构简单,故而不能做太复杂的事情,那么怎么提升预测的准确率了?一个有效的方法就是迁移学习。 迁移学习其…

C++反转链表递归

文章目录 题目描述解题思路代码复杂度分析 题目描述 LCR 024. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 解题思路 这里我们采用递归的思路来解决首先我们分为两个视角来查看…