bootstrap + django的简单后台管理系统

使用的是django3.0版本,数据库使用的是mysql1.0版本的
项目所包含的文件如下图:

登录页面

需要实现功能:
1、用户输入的用户名,密码和验证码能在后台获取
2、将获取的数据进入到数据库查找
3、成功登录后,将用户存储一个cookie在浏览器的session里面
4、判断本机用户是否有cookie存储在session里,有就可以访问系统里的所有页面,否则直接跳到登录页面。
采用form组件来实现数据的改查,MiddleForm中间件来控制访问其他页面的条件,未登录过则不可以访问系统其他页面。

Form和MiddleForm的书写

# 登录Form
class LoginForm(BootstrapForm):
    username = forms.CharField(label="用户名",
                               widget=forms.TextInput)
    password = forms.CharField(label="密码",
                               widget=forms.PasswordInput(render_value=True))
    image_code = forms.CharField(label='验证码', widget=forms.TextInput)

    def clean_password(self):
        """将得到的密码加密"""
        pwd = self.cleaned_data.get('password')
        return md5(pwd)


# 中间件
class M1(MiddlewareMixin):
    """中间件设置每个网页的访问限制"""
    def process_request(self, request):
        # 判断地址栏地址决定网页是否可直接访问
        if request.path_info in ['/login/', '/img_code/']:
            return  # return 后执行下一步方法

        # 判断该用户是否在session里有存储信息,有则可以进入
        if request.session.get('info'):
            return

        # 无存储信息,进入到登录页面
        return redirect('/login')

    # def process_response(self, request, response):
    #     print("走了")
    #     return response  # 不能忘了这一步


HTML代码:

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}">
    <script src="{% static 'plugin/jquery-3.6.0.js' %}"></script>
    <script src="{% static 'plugin/bootstrap.min.js' %}"></script>
    <style type="text/css">
        .login_form{
            position: fixed;
            width: 350px;
            height: 370px;
            top: 0;
            bottom: 0;
            right: 0;
            left: 0;
            margin:auto;
            border-radius: 10px;
            box-shadow: 14px 15px 19px -3px;
        }

        h2{ 
            text-align: center;
            margin-bottom: 18px;
            margin-top: 30px;
        }

        input{
            margin: 10px 0;
        }

        .form-group{
            height: 74px;
            margin-bottom: 0;
        }

        .form-group label{
            height: 30px;
            font-size: 16px;
            margin-top: 8px;
        }

        input[type="submit"]{
            font-size: 16px;
        }

        #id_image_code{
            width: 61%;
        }
        img{
            margin-top: 10px;
            margin-left: -40px;
        }

    </style>
</head>
<body>
    <div class="container">
        <div class="login_form">
            <h2>用户登录</h2>
            <form class="form-horizontal" method="POST" novalidate>
                {% csrf_token %}
                <div class="form-group">
                    <label class="control-label col-sm-3">用户名</label>
                    <div class="col-sm-8">
                      {{forms.username}}
                      <span style="color: red;">{{forms.username.errors.0}}</span>
                    </div>
                </div>
                <div class="form-group">
                    <label class="control-label col-sm-3">密码</label>
                    <div class="col-sm-8">
                      {{forms.password}}
                      <span style="color: red;">{{forms.password.errors.0}}</span>
                    </div>
                </div>
                <div class="form-group">
                    <label class="control-label col-sm-3">验证码</label>
                    <div class="col-sm-5">
                        {{forms.image_code}}
                        <span style="color: red;">{{forms.image_code.errors.0}}</span>
                    </div>
                    <div class="col-sm-4" style="padding: 0"><img src="/img_code"></div>
                </div>
                <input type="submit" class="btn btn-primary col-sm-4 col-sm-offset-4" value="登录">
            </form>
        </div>
    </div>


</body>
</html>

效果演示图

信息管理页面

其中包括了员工信息管理,部门信息管理,靓号信息管理,管理员信息管理和订单信息管理。
这些页面的样式基本一致,只是存在着部分功能的不同,因此,采用django中模板继承的方法,将公共部分都写在母版里,再通过模板语言书写不同的样式部分。

母版HTML代码

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>员工管理系统</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    {%block css %}{%endblock%}
    <script src="{% static 'plugin/jquery-3.6.0.js' %}"></script>
    <script src="{% static 'plugin/bootstrap.min.js' %}"></script>
    {%block js%}{%endblock%}
    <style type="text/css">
        th,td{
            text-align: center;
        }
    </style>
</head>
<body style="position: relative;">
    <nav class="navbar navbar-default">
        <div class="container">
            <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="/staffsInfo">联通员工管理系统</a>
            </div>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

            <ul class="nav navbar-nav">
                <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="/staffsInfo">员工信息管理</a></li>
                        <li ><a href="/departsInfo">部门管理</a></li>
                        <li><a href="/niceTels">靓号管理</a></li>
                        <li><a href="/admins">管理员信息</a></li>
                        <li><a href="/orders">订单信息</a></li>
                    </ul>
                </li>
                <li><a href="/tasks">ajax测试页面</a></li>
                <li><a href="/data_show">数据统计页面</a></li>
                <li><a href="/upload">文件上传</a></li>

            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li class="dropdown">
                  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{request.session.info.name}} 
                    <span class="caret">
                        <ul class="dropdown-menu">
                            <li><a href="#">个人中心</a></li>
                            <li><a href="#">我的信息</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="/logout">注销</a></li>
                        </ul>
                  </span></a>
                </li>
            </ul>
            </div>
        </div>
    </nav>
    <div>
        {% block content %}{% endblock%}
    </div>
    <!-- 分页 -->
    <div class="container">
        <nav aria-label="...">
            <ul class="pagination">
            {{pages}}
            </ul>
        </nav>
    </div>
</body>
</html>
  • {% load static %} : 用于导入应用下的静态文件
  • {%block css %} {%endblock%} : 中间填写每个页面独有的css
  • {%block js%} {%endblock%} : 中间填写每个页面独有的js
  • {% block content %} {% endblock%} : 中间填写每个页面独有的html

管理员信息

{% extends 'layout.html' %}

{% block content %}
    <div class="main">
        <div class="container">
            <div style="margin-bottom: 10px;">
                <a href="add/" class="btn btn-success">
                添加管理员
                <span class="glyphicon glyphicon-plus"></span>
                </a>
            </div>
            <div class="panel panel-default ">
                <div class="panel-heading">
                    <span class="glyphicon glyphicon-th-list"></span>
                    管理员信息列表
                </div>
                <table class="table table-bordered">
                        <thead >
                            <tr>
                                <th>ID</th>
                                <th>用户名</th>
                                <th>密码</th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for admin in admins %}
                            <tr>
                                <th scope="row">{{admin.id}}</th>
                                <td>{{admin.username}}</td>
                                <td>{{admin.password}}</td>
                                <td>
                                    <a href="update/{{admin.id}}" class="btn btn-primary btn-sm">密码重置</a>
                                    <a href="delete/{{admin.id}}" class="btn btn-danger btn-sm">删除</a>
                                </td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
            </div>
        </div>
    </div>
{% endblock %}

展示图:
在这里插入图片描述

以下代码使用模板语言中的循环,获取数据库中对应的数据信息,然后展示在页面中。
其中密码重置和删除的地址对应的是视图函数所绑定的url执行对应的功能

      {% for admin in admins %}
        <tr>
            <th scope="row">{{admin.id}}</th>
            <td>{{admin.username}}</td>
            <td>{{admin.password}}</td>
            <td>
                <a href="update/{{admin.id}}" class="btn btn-primary btn-sm">密码重置</a>
                <a href="delete/{{admin.id}}" class="btn btn-danger btn-sm">删除</a>
            </td>
        </tr>
        {% endfor %}

各种功能页面

  • 添加
    在这里插入图片描述
  • 密码重置
    在这里插入图片描述
  • 删除

点击删除后直接从数据库中删除对应数据。

Ajax数据传输

订单页面,点击新建,弹出输入模态框。
在这里插入图片描述
在这里插入图片描述

JS部分

{%block js%}
<script type="text/javascript">
	$(function(){
		var $btn_new = $('#btn_new')
		var $btn1 = $('#btn1')
		$btn_new.click(function(){
			// alert('ok')
			$('#myModal').modal('show')
		})
		$btn1.click(function(){
			$('.error').empty(); //点击一开始就清空错误信息,在重新获取错误
			$.ajax({
				url: "/tasks/ajax/",
				type: "post",
				dataType: 'JSON',
				data: $('#form').serialize() //转换以字典的格式传给后台
				})
			.done(function(dat){
				console.log(dat.statu)
				if (dat.statu == true){
					// console.log('ok')
					alert('添加成功!');
					// 获取的是个Queryset,得取其中的对象,才能清空表单内容
					$('#form')[0].reset();
					// 添加成功后隐藏模态框
					$('#myModal').modal('hide');
					location.reload();
				}
				else {
					$.each(dat.errors,function(name, error){
					$('#id_' + name).next().html(error)
					$('#id_' + name).focus(function(){
						$(this).next().empty()
					})
				})
				}
			})
			.fail(function(){
				console.log('失败了')
			})
		})


	})
</script>

{%endblock%}

数据统计页面

使用的是百度的echarts来进行绘图,还可以使用highcharts,echarts是借鉴于highcharts。数据暂时是在后台写定,实际是从数据库获取,但是基本写法一致。

在这里插入图片描述

JS部分

{% load static %}

{%block js%}
<script type="text/javascript" src="{% static 'js/echarts.js' %}"></script>
<script type="text/javascript">
    /**
     *
    报错:
     Uncaught Error: Initialize failed: invalid dom.
        init$1 http://127.0.0.1:8000/static/js/echarts.js:30192
        <anonymous> http://127.0.0.1:8000/data_show/:21 
    原因: 
        我的js代码段写在body标签之前,浏览器加载时会先去解析js代码,当浏览器执行document.getElementById('main')时,由于id为main的dom对象还未被创建,报错Initialize failed: invalid dom.
    解决:
        加上jquery的ready方法
     **/

     $(function(){
        Initbar();
        Initline();
        Initpie();
        })

     function AjaxDatas(dat, option, myChart){
        $.ajax({
            url: '/data_show/data_request/',
            type: 'POST',
            data: {num: dat},
            dataType:'JSON'
        }).done(function(data){
            console.log(data);
            if (dat == 3){
                option.series[0].data = data.series;
            }
            else{
                option.legend.data = data.legend_data;
                option.xAxis.data = data.xAxis_data;
                option.series = data.series;
            }
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
        })
     }

    function Initbar(){
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('bar'));

        // 指定图表的配置项和数据
        var option = {
            title: {
            text: '员工业绩数据显示',
            left: 'center'
            },
            tooltip: {},
            legend: {
            data: [],
            bottom: 0
            },
            xAxis: {
            data: [],
            bottom: 0
            },
            yAxis: {},
            series: []
        };
        AjaxDatas(1, option, myChart);
    }

    function Initline(){
        var chartDom = document.getElementById('line');
        var myChart = echarts.init(chartDom);
        var option;
        option = {
            title: {
                text: '公司一周业绩数据展示',
                left: 'center'
                },
            tooltip: {},
            legend: {
            data: [],
            bottom: 0
            },
          xAxis: {
            type: 'category',
            data: []
          },
          yAxis: {
            type: 'value'
          },
          series: []
        };

        AjaxDatas(2, option, myChart);
    }

    function Initpie(){
        var chartDom = document.getElementById('pie');
        var myChart = echarts.init(chartDom);
        var option;

        option = {
          title: {
            text: '员工业绩占比图',
            subtext: '上海分公司',
            left: 'center'
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: 'vertical',
            left: 'left',
            bottom:0
          },
          series: [
            {
              name: '业绩量',
              type: 'pie',
              radius: '50%',
              data: [],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        };

        AjaxDatas(3, option, myChart);
    }
      
</script>
{%endblock%}

文件上传

能够上传各种数据,例子为上传图片,读取后并将其存储在数据库,存取的图片信息是展示地址,通过浏览器地址栏输入地址就可以访问。
在这里插入图片描述

HTML部分代码

        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">文件信息上传ModelForm方式(混合数据)</h3>
            </div>
            <div class="panel-body">
                <form method="POST" enctype="multipart/form-data" novalidate>
                  <!--       通过ModelForm组件,创建输入框,然后获取数据,判断对错,保存到数据库。 -->
              <!-- {% csrf_token %}使用来赋予权限能够通过POST方法想后台发送数据
                    {% csrf_token %} -->
                    {% csrf_token %}
                    {% for form in forms2 %}
                    <div class="form-group" >
                        <label>{{form.label}}</label>
                        {{form}}
                        <span class="error" style="color: red">{{form.errors.0}}</span>
                    </div>
                    {% endfor %}
                    <input type="submit" value="提交3" class="btn btn-info" name="submit">
                </form>
            </div>
        </div>
    </div>
    <div class="main">
        <div class="container">
            <div class="panel panel-default ">
                <div class="panel-heading">
                    <span class="glyphicon glyphicon-th-list"></span>
                    文件信息列表
                </div>
                <table class="table table-bordered">
                        <thead >
                            <tr>
                                <th>ID</th>
                                <th>用户名</th>
                                <th>头像</th>
                                <th>密码</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for file in files %}
                            <tr>
                                <th scope="row">{{file.id}}</th>
                                <td>{{file.username}}</td>
                                <td>
                                    <img src="/{{file.file}}" style="height: 100px;">
                                </td>
                                <td>{{file.password}}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
            </div>
        </div>
    </div>

关键部分:

<!--       通过ModelForm组件,创建输入框,然后获取数据,判断对错,保存到数据库。 -->
<!-- {% csrf_token %}使用来赋予权限能够通过POST方法想后台发送数据
  {% csrf_token %} -->
  {% csrf_token %}
  {% for form in forms2 %}
  <div class="form-group" >
      <label>{{form.label}}</label>
      {{form}}
       <!-- 将错误显示在页面上 -->
      <span class="error" style="color: red">{{form.errors.0}}</span>
  </div>
  {% endfor %}

Python代码部分

import os.path
from django.conf import settings
from InfosShow import models
from django.http import HttpResponse
from django.shortcuts import render, redirect
from InfosShow.static.utils.pagination import Pagination
from InfosShow.static.utils.form import FileForm, FileModelForm


def upload(request):
    forms1 = FileForm()
    forms2 = FileModelForm()
    files = models.FileInfo.objects.all()
    pagination = Pagination(request, files, plus=3)
    content = {
        'forms1': forms1,
        'forms2': forms2,
        'files': pagination.queryset_list,
        'pages': pagination.run()
    }
    if request.method == 'GET':
        return render(request, 'upload_test.html', content)
    # 读取上传来的文件,获得一个对象
    file_object = request.FILES.get('file')
    submit = request.POST.get('submit')
    img_show_path = ''
    if file_object:
        print(submit)
        name = file_object.name
        print(request.POST.get('submit'))
        print(name)
        # 地址拼接
        # 网页查看图片的地址
        # static使用与存放静态文件js, css, html等的,而么media是用于存放上传来的数据的。
        # media/img1.jpg
        img_show_path = os.path.join('media', name)  # 相对路径
        # 图片保存位置
        # /home/jisoo/Django_project/SIMS/media/img1.jpg
        # img_show_path = os.path.join(settings.MEDIA_ROOT, name)  # 绝对路径
        # img_path = os.path.join('InfosShow', 'static', 'img', name)  # 保存在static下的路径
        f = open(img_show_path, mode='wb')
        # 上传的文件是一块一块的,因此需要一块块读取然后进行存储。用到chunks方法
        for chunk in file_object.chunks():
            f.write(chunk)
        f.close()
    if submit == '提交2':
        forms1 = FileForm(data=request.POST, files=request.FILES)
        if forms1.is_valid():
            print(forms1.cleaned_data)
        else:
            print(forms1.errors)
            return render(request, 'upload_test.html', {'forms1': forms1, 'forms2': forms2})
    elif submit == '提交3':
        forms2 = FileModelForm(data=request.POST, files=request.FILES)
        if forms2.is_valid():
            forms2.instance.file = img_show_path
            forms2.save()
        else:
            return render(request, 'upload_test.html', {'forms1': forms1, 'forms2': forms2})

    return redirect('/upload')


要是media得需要提前配置

media配置

在urls.py中进行配置:

from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings

urlpatterns = [
	re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
]

在settings.py中进行配置:

import os

MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"

补充

具体的一些细节功能没有拉出来单讲,比如

  • 验证码的实现
  • 分页功能的实现
  • 编辑,删除,添加功能的具体实现
  • 登录后导航栏显示用户名,点击注销后,浏览器里session关于该用户的cookie会被删除,要访问系统页面需要重新登录。

看到这的大神或是跟我一样的初学者,如果我这有任何问题,或是你有相关这些的问题,欢迎私信评论,我会认真学习,并讨论。

  • 5
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用PythonDjangoBootstrap可以很容易地实现一个用户管理系统。首先,我们需要安装PythonDjango。然后,创建一个新的Django项目,并命名为"UserManagementSystem"。 接下来,我们可以使用Django的认证系统来处理用户的注册、登录和认证功能。在Django的settings.py文件中,我们需要配置数据库连接和认证系统的一些设置。然后,我们可以创建一个名为"accounts"的应用程序来处理用户管理。 在"accounts"应用程序中,我们需要创建一些模型类来表示用户和其他相关信息,如个人资料。我们可以使用Django的内置用户模型或自定义用户模型来存储用户的用户名、密码和其他信息。然后,我们可以在模型类中定义一些验证和逻辑来确保用户数据的完整性和安全性。 接下来,我们可以使用Django的视图函数和模板来处理用户的交互。我们可以创建注册、登录和个人资料编辑的视图函数,并将它们与特定的URL进行绑定。在模板中,我们可以使用Bootstrap来美化用户界面,并使用Django的表单功能来处理用户输入和验证。 最后,我们可以使用Django的管理后台来管理用户数据。我们可以创建一个超级用户,并使用Django的管理后台来查看、编辑和删除用户数据。我们可以定制管理后台的界面,并添加一些自定义的功能来满足特定的需求。 总结来说,使用PythonDjangoBootstrap可以轻松实现一个用户管理系统。通过合理的架构和使用Django的各种功能,我们能够快速建立一个安全和高效的用户管理系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值