dvadmin-Pro学习笔记

项目初始化

前端

开发

# 克隆项目
git clone https://gitee.com/dvadmin/django-vue-admin-pro.git

# 进入项目目录
cd web

# 安装依赖
npm install --registry=https://registry.npm.taobao.org

# 启动服务
npm run dev
# 浏览器访问 http://localhost:8080
# .env.development 文件中可配置启动端口等参数

发布

# 构建测试环境
npm run build:stage

# 构建生产环境
npm run build:prod

准备数据库

#建库 mysql库名如 dv 语句如下
CREATE DATABASE IF NOT EXISTS dv DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

后端

1. 进入项目目录 cd backend
2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py
3. 在 env.py 中配置数据库信息(上面刚建立的库)
4. 安装依赖环境
	pip3 install -r requirements.txt
5. 执行迁移命令:
	python3 manage.py makemigrations
	python3 manage.py migrate
6. 初始化数据
	python3 manage.py init
7. 启动项目
	python3 manage.py runserver 127.0.0.1:8000
或使用 daphne :
  daphne -b 0.0.0.0 -8000 application.asgi:application
初始账号:superadmin 密码:admin123456
后端接口文档地址:http://127.0.0.1:8000/swagger

新建一个页面

举例新建一个图书管理的增删改查页面

后端

  • Django创建app

    #进入后端目录
    cd backend
    #新建一个后端应用名称为book
    python3 manage.py startapp book
    
  • 建表,修改models.py文件,位于 backend/book下,内容如下

    from django.db import models
    from dvadmin.utils.models import CoreModel, table_prefix
    
    
    class Book(CoreModel):
        book_no = models.CharField(max_length=24,unique=True, verbose_name='书籍编号', help_text="书籍编号")
        book_name = models.CharField(max_length=24,null=False, verbose_name='书籍名称', help_text="书籍名称")
    
    
        class Meta:
            db_table = table_prefix + "book"
            verbose_name = '书籍表'
            verbose_name_plural = verbose_name
            ordering = ('-create_datetime',)
    
  • Setting 注册一下app 路径backend/application/settings.py book加到最后 参考如下

    INSTALLED_APPS = [
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django_comment_migrate',
        'rest_framework',
        'django_filters',
        'corsheaders',  # 注册跨域app
        'dvadmin.system',
        'drf_yasg',
        'captcha',
        'book',
    ]
    
  • 迁移数据库,创建book表,book表会继承CoreModel里面定义的基础核心字段

    python3 manage.py makemigrations book
    python3 manage.py migrate book
    
  • 创建过滤器、序列化器、视图 全部写在views.py里面

    
    # Create your views here.
    
    from book.models import Book
    from dvadmin.utils.serializers import CustomModelSerializer
    from dvadmin.utils.viewset import CustomModelViewSet
    
    
    class BookSerializer(CustomModelSerializer):
        """
        书籍-序列化器
        """
    
        class Meta:
            model = Book
            fields = "__all__"
            read_only_fields = ["id"]
    
    
    class BookCreateUpdateSerializer(CustomModelSerializer):
        """
        书籍管理 创建/更新时的列化器
        """
    
        class Meta:
            model = Book
            fields = '__all__'
    
    
    class BookViewSet(CustomModelViewSet):
        """
        书籍管理接口
        list:查询
        create:新增
        update:修改
        retrieve:单例
        destroy:删除
        """
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        extra_filter_backends = []
        permission_classes = []
        search_fields = ['label']
    
    
  • 添加路由

    在book目录下添加urls.py文件,内容如下

    from rest_framework import routers
    
    from book.views import BookViewSet
    
    
    
    book_url = routers.SimpleRouter()
    book_url.register(r'book', BookViewSet)
    
    urlpatterns = []
    urlpatterns += book_url.urls
    

    在backend/application目录下添加上面的路由 urlpatterns 加入下面的内容

    path('api/', include('book.urls')),
    
  • 测试接口

    #访问swagger 测试后端接口  登录账号上面写了  确认有book的接口了 后端完成
    http://127.0.0.1:8000 
    

  • ...

前端

在 src/view 下新建目录book 然后新建三个文件 api.js curd.js index.vue

  • api.js

    import { request } from '@/api/service'
    export const urlPrefix = '/api/book/'
    
    /**
     * 列表查询
     */
    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 }
      })
    }
    
  • curd.js

    import { request } from '@/api/service'
    import { BUTTON_STATUS_NUMBER } from '@/config/button'
    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: {
           140,
          view: {
            thin: true,
            text: '',
            disabled () {
              return !vm.hasPermissions('Retrieve')
            }
          },
          edit: {
            thin: true,
            text: '',
            disabled () {
              return !vm.hasPermissions('Update')
            }
          },
          remove: {
            thin: true,
            text: '',
            disabled () {
              return !vm.hasPermissions('Delete')
            }
          }
        },
        indexRow: { // 或者直接传true,不显示title,不居中
          title: '序号',
          align: 'center',
           100
        },
        viewOptions: {
          componentType: 'form'
        },
        formOptions: {
          defaultSpan: 24, // 默认的表单 span
           '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',
          show: false,
          disabled: true,
           90,
          form: {
            disabled: true
          }
        },
        {
          title: '书籍编码',
          key: 'book_no',
          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: 'book_name',
          sortable: true,
    
          search: {
            disabled: false,
            component: {
              props: {
                clearable: true
              }
            }
          },
    
          type: 'input',
          form: {
            rules: [ // 表单校验规则
              { required: true, message: '显示值必填项' }
            ],
            component: {
              props: {
                clearable: true
              },
              placeholder: '请输入显示值'
            },
            itemProps: {
              class: { yxtInput: true }
            }
          }
        },
        ].concat(vm.commonEndColumns())
      }
    }
    
    
  • index.vue 主要要改下面的 name: 'book', 修改成实际的名字

    <template>
      <d2-container :class="{ 'page-compact': crud.pageOptions.compact }">
        <!--    <template slot="header">测试页面1</template>-->
        <d2-crud-x ref="d2Crud" v-bind="_crudProps" v-on="_crudListeners">
          <div slot="header">
            <crud-search
              ref="search"
              :options="crud.searchOptions"
              @submit="handleSearch"
            />
            <el-button-group>
              <el-button size="small" type="primary" @click="addRow"
                ><i class="el-icon-plus" /> 新增</el-button
              >
            </el-button-group>
            <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: 'book',
      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>
    
    

菜单管理

新增页面

新增页面权限

新增

编辑

删除

查询

最后展示页面完成效果

原文地址:https://www.cnblogs.com/xlovepython/p/15494011.html