6.nicegui太酷了!用nicegui设计一个很丑的后台管理系统(一)
0.系列文章入口:
1.背景描述:
最近经常有粉丝反馈,用nicegui能不能做一个管理系统。这个问题其实大可放心,nicegui其实是quasar+fastapi的合成体,也就是说既包含了前端展示也包含了后端处理,开发一个管理系统自然没有问题。既然能力上支持,那究竟怎么实现呢?那就试着写写呗,咱们一步一步来。
PS:笔者是个数据从业者,对于系统开发也只是一知半解,不要太期待功能完善,有需求、想法可以加好友聊聊,共同学习呗~
2.梳理需求:
- 用户管理
管理系统离不开用户管理,包括用户的注册、删除、权限管理等等,好在上一回已经实现了基于nicegui的用户登录页面,不知道的可以往前翻一翻。需求1:我们先简便一点儿,就设计两种角色,一种超级管理员,一种普通用户。
- 内容管理
再简单的后台管理系统,也得发布点儿内容吧,要不然还管理啥。需求2:做一个简单的文字发布功能,发布后的文字可以在系统首页被他人看到。
- 系统设置
系统设置得区分成“管理员设置(系统全局)”和“用户设置”。管理员可以设置系统全局的配置项,用户设置则只能更改自身相关的配置信息。需求3:最最基础的设置。管理员设置(可修改网站名称),用户设置(可修改密码)。
- 首页
把“首页”需求放到最后的也是没谁了。首页展示一下每个人发布的内容就好,刚开始,慢慢来~需求4:每个人发布的内容作为一个card,在网格布局中展示。
3.用到nicegui中的一些特性:
这次系统用到的nicegui特性,大部分在前面的文章中都介绍了,像网格布局、导航栏、网页title、用户登录等等,想不起来的翻前面文章,这里不再赘述。
- nicegui的路由
@ui.page
装饰下的函数,需要显示地被引用,才能被程序找到相应的路径
4.先上效果
!
5.关于一些共识
我写的未必标准,但是为了后面方便,还是先定个基调,为了以后聊起来更方便。后期也许会改,改的目的也是为了更合理,所以整体目标还是“够用就好”!
-
目录结构
- assets目录
存放网站的静态文件,比如favicon.png等。 - DB目录
存放数据库相关操作。其中DB.py用于初始化数据库连接,和关闭数据库等操作;Models.py中定义了数据表结构;CRUD.py中定义了增删改查等一系列操作,后期看情况会进行拆分。 - Sections目录
存放导航栏的相关文件,每个子目录代表一个导航菜单及其相关侧边栏。本系统现在只有Home(首页)和Admin(管理后台页)。 - db2.db和site.conf
系统在启动后会初始化db文件及网站配置文件。
- assets目录
-
导航栏的编辑
- 在Sections目录下新建文件夹,并在新建文件夹下编辑界面文件。
- 在settings中编辑变量Sections,(网页title,网页地址)
-
侧边栏的编辑
- 在导航栏对应的目录中新建Side开头的类,例如本例子中的Sections/Admin/SideUser.py、Sections/Admin/SideSystemSetting.py等
- 修改每个导航栏对应的Conf.py文件,例如Sections/Admin/PageAdminConf.py文件,修改其中的LEFT_NAVS变量,与导航栏编辑方式一致
-
文件命名规则
- 页面主页 以Page开头,例如PageAdmin.py、PageHome.py
- 侧边栏以Side开头,例如SideUser.py
- 页面配置文件与页面主页同名,后缀加上Conf,例如PageAdminConf.py
6.示例代码:
工程越来越大,只对部分代码进行说明,全部代码欢迎从仓库拉取。
- 主函数
from Sections.Admin.PageAdmin import page_admin
from Sections.Home.PageHome import page_home
from nicegui import ui,app,Client
from fastapi import Request
from fastapi.responses import RedirectResponse
from starlette.middleware.base import BaseHTTPMiddleware
from Login import login
from DB.DB import init_db,close_db
from settings import unrestricted_page_routes,ROOT
import os
import json
#2.认证中间件(这部分改的官方样例),用来判断登录状态,及未认证情况下的操作
class AuthMiddleware(BaseHTTPMiddleware):
"""This middleware restricts access to all NiceGUI pages.
It redirects the user to the login page if they are not authenticated.
"""
async def dispatch(self, request: Request, call_next):
#3.判断是否登录
if not app.storage.user.get('authenticated', False):
#4.如果未登录,并且页面需要登录后可见,就重定向到login页面
if request.url.path in Client.page_routes.values() and request.url.path not in unrestricted_page_routes:
app.storage.user['referrer_path'] = request.url.path
return RedirectResponse('/login')
return await call_next(request)
#5.在应用启动时,初始化数据库(定义数据表,这里用的是sqlite,会自动创建db2.db文件)
app.on_startup(init_db)
#6.在应用销毁时,关闭数据库连接
app.on_shutdown(close_db)
#7.挂载“认证中间件”
app.add_middleware(AuthMiddleware)
ui.run(storage_secret="abc",favicon= ROOT / "assets" / "favicon.png")
- PageHome.py中定义了程序入口
from nicegui import ui ,app
from frame import frame
from DB.CRUD import *
from fastapi import Request,Depends
from settings import get_db
import os
import json
class PageHome:
def __init__(self,db) -> None:
self.db = db
self.page_title = "首页"
def show(self):
with frame(self.page_title,left_navs=[],show_drawer=False):
with ui.grid(columns=4).classes("w-full"):
for msg_obj_i in query_all_message(self.db):
with ui.card().tight():
ui.label(f"{msg_obj_i.uname}说:{msg_obj_i.msg_title}").classes("text-h6")
with ui.card_section():
ui.label(msg_obj_i.msg_content)
@ui.page("/")
def page_home(db:Session = Depends(get_db)):
"""
默认进入的网页,首页
"""
#加载网站配置
def update_site_conf() :
if os.path.exists('site.conf'):
with open('site.conf') as fp:
app.storage.user['site_conf'] = json.load(fp)
else:
app.storage.user['site_conf'] = {"site_name":"XXX后台管理系统"}
update_site_conf()
page = PageHome(db)
page.show()
- PageAdmin.py中定义了/admin路由下的页面,并显示引用相关路由
from nicegui import ui ,app
from frame import frame
from Sections.Admin.PageAdminConf import LEFT_NAVS
from DB.CRUD import *
from fastapi import Request,Depends
from settings import get_db
"""
显示引用相关路由
"""
from Sections.Admin.SideSystemSetting import side_system
from Sections.Admin.SideUser import side_user
class PageAdmin:
def __init__(self,db) -> None:
self.page_title = "系统管理"
self.db = db
def show(self):
uid = app.storage.user["uid"]
with frame(self.page_title,left_navs= LEFT_NAVS ,show_drawer=True):
with ui.column():
ui_msg_title = ui.input("输入信息名称")
ui_msg_content = ui.textarea("输入信息内容")
ui.button("提交",on_click=lambda x: create_message(self.db,uid = uid,msg_title=ui_msg_title.value,msg_content=ui_msg_content.value))
@ui.page("/admin")
def page_admin(db:Session = Depends(get_db)):
"""
"""
page = PageAdmin(db)
page.show()
7.源码放在:
- nicegui够用就好系列代码(逐步建设中):
[github](https://github.com/thekingofhero2/nicegui-enough.git) - 便于访问,也在码云上进行了同步:
[gitee](https://gitee.com/thekingofhero/nicegui-enough.git)
8.后记
这篇博文纯属抛砖引玉,写的不好还请见谅,欢迎多多拍砖~
关注我,持续更新更多好文~