中国建设教育协会网站查询,什么是网站的原型,一键转发到wordpress,wordpress 默认图片用户管理专栏主页面开发 写在前面用户权限控制用户列表接口设计主页面开发前端account/Index.vuelangs/zh.jsstore.js 后端Paginator概述基本用法代码示例属性与方法 urls.pyviews.py 运行效果 总结 欢迎加入Gerapy二次开发教程专栏#xff01; 本专栏专为新手开发者精心策划了… 用户管理专栏主页面开发 写在前面用户权限控制用户列表接口设计主页面开发前端account/Index.vuelangs/zh.jsstore.js 后端Paginator概述基本用法代码示例属性与方法 urls.pyviews.py 运行效果 总结 欢迎加入Gerapy二次开发教程专栏 本专栏专为新手开发者精心策划了一系列内容旨在引领你深入探索Gerapy框架的二次迭代之旅。 本专栏将全面剖析Gerapy与Vue的源码架构让你从内部了解它们的运作机制。 我们将分享实用的技巧教你如何有效修复Gerapy中的异常问题如何在现有基础上添加多样化的功能以及如何对已有功能进行重构优化。 写在前面
读完本篇博客你可以学习到的知识
如何进行用户权限控制如何设计列表页翻页接口加深前后端开发经验利用Django Paginator实现翻页请求
用户权限控制
一般情况下超级管理员只会有一两个我们想在前端知道登录用户的身份的话必须要后端提供对应标识但是现在已知的接口和缓存都没有存储用户身份标识那么就需要我们重新开发提供了。
再来看下auth_user表is_superuser就是用来标识超级管理员身份 这里就有两个方案了
单独开一个接口获取当前登录用户身份由于刚好是操作auth_user表用到可以在拿auth_user表数据时顺便计算返回
这里看大家自己的选择下面我用的是第二个方案也就是每次请求列表页时会返回is_superuser字段标识用户身份。
用户列表接口设计
接口/api/account/list?pageSize10currentPage1请求GET页数参数pageSize页码参数currentPage响应接口字段
主页面开发
这是后续我们需要用到的四个文件的作用Status.vue不需要用到删除即可 前端
account/Index.vue
下面是全部代码有些注释具体的大家得自己熟悉熟悉没法仔细讲不过流程是清晰的。
templatediv classpanelpanel-title :title$lang.objects.accounts!--新增按钮实现--router-link :to{ name: accountCreate } tagspanel-button sizemini typesuccessi classfa fa-plus/i{{ $lang.buttons.create }}/el-button/router-link/panel-titlediv classpanel-body!--遍历accounts--el-tablev-loadingloading:dataaccounts:element-loading-text$lang.messages.loading:empty-text$lang.messages.noData:style{ width: 100%; }!--各字段呈现实现--el-table-column:label$lang.columns.usernamealigncenterpropusernamemin-width30%/el-table-columnel-table-column:label$lang.columns.emailaligncenterpropemailmin-width30%/el-table-columnel-table-column :label$lang.columns.is_superuser aligncenter min-width30%template slot-scopepropsspan v-ifprops.row.is_superuserel-button iconel-icon-check round sizemini typeprimary/el-button/spanspan v-elseel-button iconel-icon-close round sizemini typeprimary/el-button/span/template/el-table-columnel-table-column :label$lang.columns.is_staff aligncenter min-width30%template slot-scopepropsspan v-ifprops.row.is_staffel-button iconel-icon-check round sizemini typeprimary/el-button/spanspan v-elseel-button iconel-icon-close round sizemini typeprimary/el-button/span/template/el-table-columnel-table-column :label$lang.columns.is_active aligncenter min-width30%template slot-scopepropsspan v-ifprops.row.is_activeel-button iconel-icon-check round sizemini typeprimary/el-button/spanspan v-elseel-button iconel-icon-close round sizemini typeprimary/el-button/span/template/el-table-columnel-table-column:label$lang.columns.date_joinedaligncenterpropdate_joinedmin-width30%/el-table-columnel-table-column:label$lang.columns.last_loginaligncenterproplast_loginmin-width30%/el-table-column!--isSupperUserLogin标识超级管理员身份--el-table-column v-ifisSupperUserLogin :label$lang.columns.operations aligncenter min-width50%template slot-scopepropsrouter-link :to{ name: accountEdit, params: { id: props.row.id } } tagspan!--指定列跳转编辑页--el-button sizemini typeinfoi classfa fa-edit/i{{ $lang.buttons.edit }}/el-button/router-link!--指定列删除--el-button sizemini typedanger clickonSingleDelete(props.row.id)i classfa fa-remove/i{{ $lang.buttons.delete }}/el-button/template/el-table-column/el-table/div/div
/template
script typetext/javascript
import PanelTitle from ../../components/PanelTitle;export default {data() {return {accounts: [], // 用户数据列表loading: true, // 加载中isSupperUserLogin: true, // 是否是超级管理员身份totalCount: 0, // 用户数据总数currentPage: 1, // 当前页码pageSize: 10, // 页数};},components: {PanelTitle,},created() {// 页面创建时请求数据this.getAccountData(this.currentPage, this.pageSize);},methods: {// 请求用户数据getAccountData(current_page, page_size) {this.loading true;// GET传参方式this.$http.get(this.$store.state.url.account.list, {params: {pageSize: page_size,currentPage: current_page,}}).then(({data: data}) {this.accounts data[rows];this.totalCount data[count];this.isSupperUserLogin data[is_superuser];this.loading false;}).catch(() {this.loading false;});},// 删除指定用户deleteAccount(id) {this.$http.post(this.formatString(this.$store.state.url.account.remove, {id: id,})).then(() {this.$message.success(this.$store.getters.$lang.messages.successDelete);this.loading false;this.getAccountData(this.currentPage, this.pageSize);}).catch(() {this.$message.error(this.$store.getters.$lang.messages.errorDelete);this.loading false;});},// 提交删除用户onSingleDelete(id) {this.$confirm(this.$store.getters.$lang.messages.confirm,this.$store.getters.$lang.buttons.confirm,{confirmButtonText: this.$store.getters.$lang.buttons.yes,cancelButtonText: this.$store.getters.$lang.buttons.no,type: warning,}).then(() {this.deleteAccount(id);});},},
};
/script
langs/zh.js
需要在columns下增加些配置参数
is_superuser: 超级用户,
is_staff: 工作人员,
is_active: 状态,
date_joined: 加入时间,
last_login: 最后登录时间,
deployed_user_name: 部署者,
deployed_client_name: 部署主机,
deployed_project_name: 部署项目,
deployed_description: 部署描述,
deployed_at: 部署时间,
priority: 优先级,store.js
需要在url下增加些配置参数
account: {list: /api/account/list,create: /api/account/create,info: /api/account/{id}/info,update: /api/account/{id}/update,remove: /api/account/{id}/remove,
},后端
Paginator
这里我们先了解一下Django的翻页器Paginator
概述
Django的Paginator是一个内置的分页组件用于将大量数据分页显示从而改善用户体验并减轻服务器压力。使用Paginator可以指定每页显示的数据项数量并生成一个分页对象该对象包含了关于总页数、当前页码等信息的方法。
基本用法
引入Paginator类首先需要从django.core.paginator模块中引入Paginator类。 创建Paginator对象使用Paginator(object_list, per_page)创建一个分页器对象其中object_list是要分页的数据列表per_page是每页显示的数据条数。 获取页面数据通过调用分页器对象的page(page_number)方法获取特定页面的数据其中page_number是页码。返回的是一个Page对象该对象提供了当前页的数据项列表以及其他分页信息如是否有下一页、上一页等。
代码示例
from django.core.paginator import Paginator# 假设有一个包含100条数据的列表
objects [item1, item2, ..., item100]
# 创建Paginator对象每页显示10条数据
paginator Paginator(objects, 10)# 获取第一页的数据
page1 paginator.page(1)
print(page1.object_list) # 输出当前页的数据项列表
print(page1.has_next()) # 检查是否有下一页
print(page1.has_previous()) # 检查是否有上一页
print(page1.number) # 当前页码
属性与方法
paginator.count: 总数据项数paginator.num_pages: 总页数paginator.page_range: 一个范围对象包含所有页码page.object_list: 当前页的数据项列表page.number: 当前页码page.has_next(): 是否有下一页page.has_previous(): 是否有上一页page.next_page_number(): 下一页的页码如果有的话page.previous_page_number(): 上一页的页码如果有的话
urls.py
新增两个接口映射
url(r^api/account/list, views.account_list, nameaccount_list),
url(r^api/account/(\d)/remove, views.account_remove, nameaccount_remove),views.py
导入需要的包
from django.contrib.auth.models import User
from django.core.paginator import Paginator方法代码开发具体实现代码有注释
log_exception()
api_view([GET])
permission_classes([IsAuthenticated])
def account_list(request):account list:param request: request object:return: jsonif request.method GET:# 获取单页页数page_size int(request.query_params.get(pageSize))# 拿到当前页current_page int(request.query_params.get(currentPage))# 根据主键id顺序排序拿到全部数据对象accounts User.objects.order_by(id)# 创建翻页器Paginator对象全部数据 单页页数paginator Paginator(accounts, page_size)# 提取指定页码的数据page_obj paginator.get_page(current_page)# model_to_dict模型数据转字典定义导出的字段fields [id, username, email, is_superuser, date_joined, last_login, is_staff, is_active]# 最后拼接数据返回return JsonResponse({currentPage: current_page, pageSize: page_size, count: paginator.count,num_pages: paginator.num_pages, is_superuser: request.user.is_superuser,rows: [model_to_dict(item, fieldsfields) for item in page_obj.object_list]})log_exception()
api_view([POST])
permission_classes([IsAuthenticated])
def account_remove(request, account_id):remove account by account_id:param request: request object:param account_id: account id:return: jsonif request.method POST:# 根据用户id查询并删除User.objects.filter(idaccount_id).delete()return JsonResponse({result: 1})运行效果
处理好后打包Vue代码重新启动后端服务刷新浏览器。 这里留个坑给大家自己实现就是删除按钮应该给超级管理员隐藏或者不可用毕竟他要是删了自己账号还管理个啥
总结
到这里我们就实现了主页面开发了接下来将实现其他页面~