【玩转全栈】----Django制作部门管理页面
大致效果
我先给个大致效果,基本融合了Django、Bootstrap、css、html等等。
基于Django的部门管理系统
BootStrap
BootStrap简介
Bootstrap 是一个由 Twitter 团队开发的开源前端框架,专注于帮助开发者快速构建响应式和现代化的网页。它基于 HTML、CSS 和 JavaScript,提供了一系列强大的组件和工具,包括栅格系统、按钮、导航栏、表单、模态框、卡片、警告框等,使网页开发变得更加高效和规范化。
Bootstrap 的核心特点是响应式设计,通过其强大的栅格系统和内置的媒体查询,开发者可以轻松创建在不同设备(如手机、平板、PC)上都能正常显示的页面。它还具有良好的跨浏览器兼容性,能够确保网页在主流浏览器中的一致性。
此外,Bootstrap 提供了丰富的可定制性,开发者可以通过修改变量或定制化 CSS 来调整样式。同时,它拥有大量社区支持和第三方资源,如模板、插件和扩展,大幅减少开发时间。Bootstrap 适用于从简单的静态网站到复杂的 Web 应用的快速开发,是现代前端开发中常用的工具之一。
BootStrap配置
需要大家自己去BootStrap官网上下载源码,然后引入即可,这里我已经给大家提供了,大家拷贝即可:
大家复制到此位置即可
引入也很简单,复制下面两行代码到html页面中,如图所示:
{% load static %}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
BootStrap使用
如果您学过vue,那一定知道element-ui,BootStrap和element-ui一样,作用都是使用组件 Demo 快速体验交互细节,帮助工程师快速开发。
BootStrap使用也很简单,打开BootStrap官网:
Bootstrap v3 中文文档 · Bootstrap 是最受欢迎的 HTML、CSS 和 JavaScript 框架,用于开发响应式布局、移动设备优先的 WEB 项目。 | Bootstrap 中文网
我这里举个使用的例子:
先找到自己需要的页面样式
复制代码到自己页面上就能显示相同的效果
像上面那个因为代码太长,官网没有直接给出源码的,可以点开F12工具,或者右键检查,定位到这个表格元素,右键table复制outerHTML代码即可。
运行得到的页面和官网差不多
有时页面也会因为自己的一些设置会有不同,可以自己修改。
基本配置
基本配置包括数据库创建和连接,可以直接用之前创建的app01_department表,有不知道的可以看看这篇:
【玩转全栈】----Django连接MySQL_django mysql-CSDN博客
像之前也写了一个用户管理案例,但页面不是很美观,基本的逻辑都是通的,本篇博客着手BootStrap组件库,带你使用BootStrap快速制作一个美观的页面。
源码展示:
用户管理大致逻辑:
urls.py:
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path("",views.depart_list),
path("depart/list/", views.depart_list),
path("depart/add/", views.depart_add),
path("depart/delete/", views.depart_delete),
path("depart/<int:nid>/edit/", views.depart_edit),
]
view.py:
from django.http import HttpResponse
from django.shortcuts import render, redirect
from app01.models import Department
import sys
def depart_list(request):
"""部门列表"""
queryset = Department.objects.all()
print(queryset)
# sys.stdout.flush() # 强制刷新输出
return render(request, "depart_list.html",{"queryset":queryset})
def depart_add(request):
if request.method == "GET":
return render(request, "depart_add.html")
else:
title = request.POST.get("title")
pwd = request.POST.get("pwd")
# 密码正确,放入数据库
if pwd == "1234":
Department.objects.create(title=title)
return redirect("/depart/list")
def depart_delete(request):
nid = request.GET.get("nid")
print(nid)
Department.objects.filter(id=nid).delete()
return redirect("/depart/list")
def depart_edit(request,nid):
# filter获取匹配的多个数据,get获取一个
obj = Department.objects.filter(id=nid).first()
if request.method == "GET":
return render(request, "depart_edit.html",{"obj":obj})
else:
title = request.POST.get("title")
pwd = request.POST.get("pwd")
if pwd == "1234":
Department.objects.filter(id=nid).update(title=title)
return redirect("/depart/list")
return render(request, "depart_edit.html", {"obj": obj})
settings文件中的数据库配置和models文件中的操作和之前博客的都一样,不用做修改。
页面:
(没学过前端并且不想学的直接复制就行,前提是前面的BoosStrap已成功导入)
depart_list.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<style>
.navbar{
border-radius: 0;
}
.my-div{
height: 600px;
width: 900px;
margin: auto ;
{#margin-top: 40px ;#}
{#margin-top: 20px;#}
border: 1px solid #d5dfe3;
padding: 20px 40px;
border-radius: 10px;
box-shadow: 5px 5px 22px #aaa;
}
</style>
</head>
<body>
{#<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>#}
{#<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>#}
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">广西联通</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">位于 <span class="sr-only">(current)</span></a></li>
<li><a href="#">时间</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">地点 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">重庆</a></li>
<li><a href="#">江西</a></li>
<li><a href="#">上海</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">福建</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">黑龙江</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
{% csrf_token %}
<label>
<input type="text" class="form-control" placeholder="Search">
</label>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li><a href="#">注册</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="my-div">
<div style="margin-bottom: 10px">
<a class="btn btn-primary" href="/depart/add/">
{# target="_blank"使得跳转打开新页面#}
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
新建部门</a>
</div>
<div>
<div class="panel-heading">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
部门列表</div>
<div class="bs-example" data-example-id="contextual-table">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>部门名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th scope="row">{
{ obj.id }}</th>
<td>{
{ obj.title }}</td>
<td>
<a class="btn btn-primary btn-xs" href="/depart/{
{ obj.id }}/edit">编辑</a>
<a class="btn btn-danger btn-xs" href="/depart/delete/?nid={
{ obj.id }}">删除</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</body>
</html>
depart_add.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加</title>
{# 压缩版本#}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<style>
.navbar{
border-radius: 0;
}
.my-div{
height: 600px;
width: 900px;
margin: auto ;
{#margin-top: 40px ;#}
{#margin-top: 20px;#}
border: 1px solid #d5dfe3;
padding: 20px 40px;
border-radius: 10px;
box-shadow: 5px 5px 22px #aaa;
}
</style>
</head>
<body>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">广西联通</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">位于 <span class="sr-only">(current)</span></a></li>
<li><a href="#">时间</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">地点 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">重庆</a></li>
<li><a href="#">江西</a></li>
<li><a href="#">上海</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">福建</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">黑龙江</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
{% csrf_token %}
<label>
<input type="text" class="form-control" placeholder="Search">
</label>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li><a href="#">注册</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="my-div">
<div class="container">
<div class="panel panel-default" style="width: 750px;margin-top: 100px">
<!-- Default panel contents -->
<div class="panel-heading">新建 部门</div>
<div class="panel-body">
<form class="form-horizontal" method="POST">
{% csrf_token %}
<!-- 部门名输入框 -->
<div class="form-group">
<label for="inputDepartmentName" class="col-sm-2 control-label">部门名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入部门名" name="title" value="XX部">
</div>
</div>
<!-- 管理员密码输入框 -->
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">管理员密码</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="请输入管理员密码" name="pwd">
</div>
</div>
<!-- 保存按钮 -->
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">保 存</button>
</div>
</div>
</form>
</div>
<!-- Table -->
<table class="table">
...
</table>
</div>
</div>
</div>
</body>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</html>
depart_edit.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加</title>
{# 压缩版本#}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<style>
.navbar{
border-radius: 0;
}
.my-div{
height: 600px;
width: 900px;
margin: auto ;
{#margin-top: 40px ;#}
{#margin-top: 20px;#}
border: 1px solid #d5dfe3;
padding: 20px 40px;
border-radius: 10px;
box-shadow: 5px 5px 22px #aaa;
}
</style>
</head>
<body>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">广西联通</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">位于 <span class="sr-only">(current)</span></a></li>
<li><a href="#">时间</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">地点 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">重庆</a></li>
<li><a href="#">江西</a></li>
<li><a href="#">上海</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">福建</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">黑龙江</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
{% csrf_token %}
<label>
<input type="text" class="form-control" placeholder="Search">
</label>
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li><a href="#">注册</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="my-div">
<div class="container">
<div class="panel panel-default" style="width: 750px;margin-top: 100px">
<!-- Default panel contents -->
<div class="panel-heading">修改 部门</div>
<div class="panel-body">
<form class="form-horizontal" method="POST">
{% csrf_token %}
<!-- 部门名输入框 -->
<div class="form-group">
<label for="inputDepartmentName" class="col-sm-2 control-label">部门名 :</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入部门名" name="title" value="{
{ obj.title }}">
</div>
</div>
<!-- 管理员密码输入框 -->
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">管理员密码 :</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="请输入管理员密码" name="pwd">
</div>
</div>
<!-- 保存按钮 -->
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">保 存</button>
</div>
</div>
</form>
</div>
<!-- Table -->
<table class="table">
...
</table>
</div>
</div>
</div>
</body>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</html>
部分代码解释及注意:
这里代码按文件分开说的话可能说不清楚,下面我将按功能解释。
用户编辑:
url.py:
path("depart/<int:nid>/edit/", views.depart_edit)
这里的<int:nid>是动态传值,之前都是学的静态url,使用正则表达式可以使url变得动态起来。这里可以理解为:用户点击编辑按钮,会获得该行的id,并通过id构造一个专属url,从而跳转到编辑页面。
在depart_list.html中有这么一句代码:
<a class="btn btn-primary btn-xs" href="/depart/{
{ obj.id }}/edit">编辑</a>
用户点击编辑后会获取点击行的id,并跳转到动态url
在视图函数中:
将获取到的nid传给视图函数,视图函数根据id获取改行数据,传给depart_edit.html,以将原数据显示到编辑页面,用户在编辑页面修改信息后,点击提交,视图函数获取新数据,再到数据库更新,然后重定向至depart_list.html页面进行更新显示。
注意:此处表单没加action,即提交地址,则默认提交到已经渲染了的视图函数。
def depart_edit(request,nid):
# filter获取匹配的多个数据,get获取一个
obj = Department.objects.filter(id=nid).first()
if request.method == "GET":
return render(request, "depart_edit.html",{"obj":obj})
else:
title = request.POST.get("title")
pwd = request.POST.get("pwd")
if pwd == "1234":
Department.objects.filter(id=nid).update(title=title)
return redirect("/depart/list")
return render(request, "depart_edit.html", {"obj": obj})
新添数据:
简单的POST请求,数据库存储,传参显示。可以参考用户编辑逻辑。
删除数据:
在depart_list.html中点击删除,获取该行的id值并构造动态url,执行对应的删除函数
<a class="btn btn-danger btn-xs" href="/depart/delete/?nid={
{ obj.id }}">删除</a>
注意id直接通过 URL 的查询参数传参,视图函数中直接GET就能拿到,然后在数据库中删除,并重定向回depart_list页面。
注意:
用户编辑中的nid和删除数据中的nid,后者实际上是专门通过url传递参数的,查询参数(Query Parameters),它会将 nid={
{ obj.id }}
作为 URL 的一部分发送到服务器。前面的是直接构造了动态url,直接通过视图函数参数列表传参,ID 是作为 URL 的一部分传递给服务器的,不是查询参数。
具体区别:
特性 | 加问号(查询参数) href="/depart/delete/?nid={
{ obj.id }}" | 不加问号(路径参数) href="/depart/delete/{
{ obj.id }}" |
---|
URL 格式 | /depart/delete/?nid={
{ obj.id }} | /depart/delete/{
{ obj.id }} |
信息传递方式 | 通过查询参数传递信息,格式为 ?key=value | 通过 URL 路径传递信息,格式为 /<value> |
服务器端获取方式 | 使用 request.GET 获取参数值 | 使用 Django URL 配置中的路径参数获取 |
适用场景 | 通常用于过滤、分页、排序等场景,或者传递附加的非核心数据 | 适用于 RESTful 风格的 API 或直接操作资源(如删除、编辑) |
Django 路由配置 | path('depart/delete/', views.depart_delete) | path('depart/delete/<int:nid>/', views.depart_delete) |
常见用途 | 用于查询、搜索、筛选、分页等 | 用于操作特定资源的唯一标识(如删除特定部门) |
SEO 友好性 | 查询参数不会显示在浏览器历史记录中,可能对搜索引擎不太友好 | 路径参数通常更直观,有时对 SEO 更有利,尤其是用于 RESTful 风格的 API |
简洁性 | URL 中包含查询参数,可能变长,参数较多时不够简洁 | URL 结构更简洁、直观,适用于表示资源层次结构 |
可读性 | 查询参数有时可能让 URL 看起来不那么直观 | 路径参数使 URL 直接指向具体的资源,通常更易于理解 |
本次的分享就到这里的,感谢大家的三连!!!