基于Django简单实现一个员工管理系统

这是Django框架从入门到精通(第四章用户管理)内附源码

文章目录


 前言:

经过前期的学习,我们掌握了最基本的用法,这期将把后面的知识点全部使用,只给大家简单说一下,具体知识点还是按流程来,给大家看一下成品:

这就是我们学习完之后的知识点,能做出来的,这个页面有些不太好看,我们可以用css来修饰,给大家看我的源码:

  • 建立数据库,并创建表: 

from django.db import models


# 部门类
class Department(models.Model):
    title = models.CharField(verbose_name='标题', max_length=32)

    def __str__(self):
        return self.title


# 员工类
class UserInfo(models.Model):
    name = models.CharField(verbose_name='姓名', max_length=16)
    password = models.CharField(verbose_name='密码', max_length=64)
    age = models.IntegerField(verbose_name='年龄')
    account = models.DecimalField(verbose_name='余额', max_digits=10, decimal_places=2, default=0)
    create_time = models.DateField(verbose_name='入职时间')
    # to与哪张表关联
    # to_field 表中的哪一列关联
    # Django 自动后面生成_id
    # 若部门删除
    # 1)级联删除 on_delete=models.CASCADE
    # 2) 置空 null=ture black=ture
    depart = models.ForeignKey(verbose_name="部门", to="Department", to_field="id", on_delete=models.CASCADE)

    gender_choices = (
        (1, "男"),
        (2, "女"),
    )
    gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)


# 管理员类
class Admin(models.Model):
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)

 这里涉及到了主键约束,和级联删除,代码中有注释

  • 建立url:

urlpatterns = [
    # path('admin/', admin.site.urls),

    path('depart/list/', views.depart_list),

    path('uesr/model/form/add/', views.user_model_form_add),

    path('main/page/', views.main_page),
    # 将id传递
    path('user/<int:nid>/edit/', views.user_edit),

    path('user/<int:nid>/data/', views.user_data),

    path('admin/list/', views.admin_list),

    path('admin/add/', views.admin_add),

    path('admin/<int:nid>/edit/', views.admin_edit),

    path('admin/<int:nid>/delet/', views.admin_delet),

    path('admin/<int:nid>/edit/password/', views.admin_edit_password),

    path('admin/login/', views.login),

    path('admin/logout/', views.logout)
]

这些都是url与函数的对应关系。

  • 主函数views.py

 首先给大家看我我们要导入的模块

# 导入forms模块
from django import forms
# 导入正则表达式
from django.core.validators import RegexValidator
# 导入自己设置报错模块
from django.core.exceptions import ValidationError
# 导入django自带的md5加密的盐
from django.conf import settings
# 导入中间件
from django.utils.deprecation import MiddlewareMixin
  •  定义md5方法将数据库加密

# 运用md5将数据库密码加密
def md5(data_string):
    obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
    obj.update(data_string.encode('utf-8'))
    return obj.hexdigest()
  •  定义bootstrap类

# 定义bootstrap类
class BootStrapModelForm(forms.ModelForm):
    # 定义init方法
    def __init__(self, *args, **kwargs):
        # 执行父类的init方法
        super().__init__(*args, **kwargs)

        # 循环modelform每一个字段,设置字段的插件
        for name, field in self.fields.items():
            if field.widget.attrs:
                # 若字典内有值
                field.widget.attrs["class"] = "form-control"
            else:
                # 若字典内有值
                field.widget.attrs = {"class": "form-control"}
  •  定义中间件

# 定义中间件
class AuthMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        # 排除不需要登陆就可以访问的页面
        if request.path_info == "/admin/login/":
            return
            # 读取访问用户的session信息
        info_dict = request.session.get("info")
        if info_dict:
            return
        # 若没登陆去登录页面
        return redirect('/admin/login/')
  • 定义modelform类并继承bootstrap类  

# 继承bootstrap类
class UserModelForm(BootStrapModelForm):
    name = forms.CharField(min_length=2,
                           label="用户名",
                           # validators=正则表达式(方式一)
                           # validators=RegexValidator())
                           )

    # 正则表达式
    RegexValidator()

    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "depart", "gender"]

    # 方式2(定义钩子方法)
    def clean_name(self):
        txt_name = self.cleaned_data["name"]
        # 钩子方法校验
        if len(txt_name) > 10:
            raise ValidationError("格式错误")

        # 验证通过返回(必须这样写)
        return txt_name
  •  定义管理员modelform类,并继承bootstrap类

# 定义新的modelform管理员密码类
# 并继承Bootstrap父类
class AdminEditPasswordModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(label="确认密码", widget=forms.PasswordInput(render_value=True))

    class Meta:
        model = models.Admin
        fields = ['password', 'confirm_password']

    def clean_password(self):
        # 获得用户输入的密码
        pwd = self.cleaned_data.get("password")
        # 用md5将数据加密
        md5_pwd = md5(pwd)
        # 在数据库中搜索id,password
        exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()
        if exists:
            raise ValidationError("重置的密码不能与之前的相同")
        return md5_pwd

    def clean_confirm_password(self):
        pwd = self.cleaned_data.get("password")
        confirm = md5(self.cleaned_data.get("confirm_password"))
        if confirm != pwd:
            raise ValidationError("账号密码不一致")
        return confirm
  •  员工类代码-增删改查

# 员工主页面
def main_page(request):
    # 去数据库中拿到所有信息
    model_user_info = models.UserInfo.objects.all()
    # 建数据库中信息传入前端
    return render(request, 'main_page.html', {"objects": model_user_info})


# 员工存储页面
def user_model_form_add(request):
    # 用户访问get方式
    if request.method == "GET":
        form = UserModelForm()
        return render(request, 'user_model_form_add.html', {"form": form})

    # 用户post请求提交数据,校验数据
    form = UserModelForm(data=request.POST)
    if form.is_valid():
        # 校验正确存入库
        form.save()
        return redirect('/main/page/')
    else:
        return render(request, 'user_model_form_add.html', {"form": form})


# 编辑员工信息
def user_edit(request, nid):
    row_object = models.UserInfo.objects.filter(id=nid).first()
    if request.method == "GET":
        form = UserModelForm(instance=row_object)
        return render(request, 'user_edit.html', {"form": form})

    elif request.method == "POST":
        form = UserModelForm(data=request.POST, instance=row_object)
        if form.is_valid():
            form.save()
            # 重定向回主页面
            return redirect('/main/page')
        return render(request, 'user_edit.html', {"form": form})


# 删除员工信息
def user_data(request, nid):
    models.UserInfo.objects.filter(id=nid).delete()
    # 删除后重定向
    return redirect('/main/page')
  •  管理员类增删改查

# 管理员列表
def admin_list(request):
    queryset = models.Admin.objects.all()
    return render(request, 'admin_list.html', {"queryset": queryset})


# 新建管理员
def admin_add(request):
    title = "新建管理员"
    if request.method == "GET":
        form = AdminModelForm()
        return render(request, 'admin_add.html', {'form': form, 'title': title})
    form = AdminModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return redirect('/admin/list/')
    return render(request, 'admin_add.html', {'form': form, "title": title})


# 编辑管理员
def admin_edit(request, nid):
    title = "管理员编辑表"
    row_object = models.Admin.objects.filter(id=nid).first()
    if not row_object:
        return redirect('/admin/list/')
    # get请求
    if request.method == 'GET':
        form = AdminModelForm(instance=row_object)
        return render(request, 'admin_edit.html', {"title": title, "queryset": form})
    # post请求保存到数据库
    elif request.method == "POST":
        form = AdminModelForm(data=request.POST, instance=row_object)
        if form.is_valid():
            # 校验正确保存到数据库
            form.save()
            return redirect('/admin/list/')
        return render(request, 'admin_edit.html', {"queryset": form})


# 删除管理员
def admin_delet(request, nid):
    models.Admin.objects.filter(id=nid).delete()
    # 重定向回列表页面
    return redirect('/admin/list/')


# 重置密码
def admin_edit_password(request, nid):
    row_object = models.Admin.objects.filter(id=nid).first()
    if not list:
        return redirect('/admin/list/')
    title = '重置管理员密码----{}'.format(row_object.username)
    if request.method == "GET":
        form = AdminEditPasswordModelForm(instance=row_object)
        return render(request, 'admin_edit_password.html', {"queryset": form, "title": title})
    elif request.method == "POST":
        form = AdminEditPasswordModelForm(data=request.POST, instance=row_object)
        if form.is_valid():
            form.save()
            return redirect('/admin/list/')
        return render(request, 'admin_edit_password.html', {"queryset": form, "title": title})


# 管理员登录类
class LoginForm(forms.Form):
    username = forms.CharField(label="用户名", widget=forms.TextInput, required=True)
    password = forms.CharField(label="密码", widget=forms.PasswordInput(render_value=True), required=True)

    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)


# 管理员登录界面
def login(request):
    if request.method == "GET":
        form = LoginForm()
        return render(request, 'login.html', {"form": form})
    elif request.method == "POST":
        form = LoginForm(data=request.POST)
        if form.is_valid():
            # 去数据库校验账号和密码,获取用户对象
            admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
            if not admin_object:
                # 主动添加错误
                form.add_error("password", "用户名或密码不正确")
                return render(request, 'login.html', {"form": form})
            # 进行cookie认证和session
            # 若正确,网站生成随机字符串,写到用户的浏览器cookie中,再写到session中
            else:
                # 写入session中
                request.session["info"] = {"id": admin_object.id, "name": admin_object.username}
                # 登录成功进行重定向
                return redirect('/main/page/')
        return render(request, 'login.html', {"form": form})


# 注销登录
def logout(request):
    request.session.clear()
    return redirect('/admin/login')

 这就是views的所有代码,给大家看一下前端的代码

 首先:

  • 管理员添加html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div>
            <h1> {{ title }}注册表</h1>
        </div>
        <form method="post" novalidate>
            <fieldset>
                {% csrf_token %}
                {% for iteam in form %}
                    <div class="form-group">
                        {{ iteam.label }}: {{ iteam }}<br><br>
                        <span style="color: red"> {{ iteam.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">
                    提交
                </button>
            </fieldset>
        </form>
    </div>
</div>
</body>
</html>
  •  修改管理员信息html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div>
            <h1> {{ title }}</h1>
        </div>
        <form method="post" novalidate>
            <fieldset>
                {% csrf_token %}
                {% for iteam in queryset %}
                    <div class="form-group">
                        {{ iteam.label }}: {{ iteam }}<br><br>
                        <span style="color: red"> {{ iteam.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">
                    提交
                </button>
            </fieldset>
        </form>
    </div>
</div>
</body>
</html>

 修改管理员密码html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div>
            <h1> {{ title }}</h1>
        </div>
        <form method="post" novalidate>
            <fieldset>
                {% csrf_token %}
                {% for iteam in queryset %}
                    <div class="form-group">
                        {{ iteam.label }}: {{ iteam }}<br><br>
                        <span style="color: red"> {{ iteam.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">
                    提交
                </button>
            </fieldset>
        </form>
    </div>
</div>
</body>
</html>
  • 管理员页面html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
</head>
<body>
<a class="btn btn-success" href="/admin/add/">新建管理员</a>
<table border="1" width="900px">  <!--border:表格边框,width:表格宽度-->
    <caption>管理员中心</caption>  <!--标题标签,居中显示,仅有一个标题-->
    <tr>
        <th>id</th>
        <th>姓名</th> <!--th标签:表格头,内容居中,加粗显示-->
        <th>密码</th>
        <th>密码操作</th>
        <th>操作</th>
    </tr>
    {% for obj in queryset %}
        <tr>
        <td> {{ obj.id }}</td>
        <td>{{ obj.username }}</td>  <!--td标签:普通表格,内容左对齐-->
        <td>*********</td>
        <td><a class="btn btn-success" href="/admin/{{ obj.id }}/edit/password/">重置密码</a></td>
        <td>
        <a class="btn-primary btn-xs" href="/admin/{{ obj.id }}/edit/">编辑</a>
        <a class="btn-danger btn-ns" href="/admin/{{ obj.id }}/delet/">删除</a>
    {% endfor %}
    </td>
    </tr>
</table>
</body>
</html>
  •  登录页面的html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
            background-size: 100% 130%;
        }

        #login_box {
            width: 20%;
            height: 400px;
            background-color: #00000060;
            margin: auto;
            margin-top: 10%;
            text-align: center;
            border-radius: 10px;
            padding: 50px 50px;
        }

        h2 {
            color: #ffffff90;
            margin-top: 5%;
        }

        #input-box {
            margin-top: 5%;
        }

        span {
            color: #fff;
        }

        input {
            border: 0;
            width: 60%;
            font-size: 30px;
            color: #fff;
            background: transparent;
            border-bottom: 6px solid #fff;
            padding: 5px 10px;
            outline: none;
            margin-top: 10px;
        }

        button {
            margin-top: 50px;
            width: 60%;
            height: 30px;
            border-radius: 10px;
            border: 0;
            color: #fff;
            text-align: center;
            line-height: 30px;
            font-size: 15px;
            background-image: linear-gradient(to right, #30cfd0, #330867);
        }

        #sign_up {
            margin-top: 45%;
            margin-left: 60%;
        }

        a {
            color: #b94648;
        }
    </style>
</head>

<body>
<form method="post" novalidate>
    {% csrf_token %}
    <div id="login_box">
        <h2>管理员登录</h2>
        <div id="input_box">
            {{ form.username.label }}:{{ form.username }}<br><br>
            <span style="color: red">{{ form.username.errors.0 }}</span>
        </div>
        <div class="input_box">
            {{ form.password.label }}:{{ form.password }}<br><br>
            <span style="color: red">{{ form.password.errors.0 }}</span>
        </div>
        <button type="submit">登录</button>
        <br>
    </div>
</form>
</body>
</html>
  •  部门添加页面html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post">
    {% csrf_token %}
    <label><input class="text" name="title" value="请添加部门"/> 部门名称</label>
    <button type="submit" class="btn btn-primary">
        提交
    </button>
</form>
</body>
</html>
  •  员工主页面html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        li {
            display: inline;
            list-style: none;
            margin: 0 20px;
        }
    </style>
</head>
<body>
<nav class="pageNav">
    <ul class="list">
        <li><a href="/main/page/" target="_blank"><span>员工管理</span></a></li>
        <li><a href="/admin/list/" target="_blank"><span>管理员管理</span></a></li>
        <li><a href="/admin/logout/" target="_blank"><span>注销</span></a></li>
        {#        <li><a href="#" target="_blank"><span>联系我们</span></a></li>#}
        <li><a href="#" target="_blank"><span>{{ request.session.info.name }}</span></a></li>
    </ul>
</nav>
<a class="btn btn-success" href="/uesr/model/form/add/">新建员工</a>
<table border="1" width="900px">  <!--border:表格边框,width:表格宽度-->
    <caption>用户信息中心</caption>  <!--标题标签,居中显示,仅有一个标题-->
    <tr>
        <th>id</th>
        <th>姓名</th> <!--th标签:表格头,内容居中,加粗显示-->
        <th>密码</th>
        <th>年龄</th>
        <th>余额</th>
        <th>入职时间</th>
        <th>性别</th>
        <th>部门</th>
        <th>操作</th>
    </tr>
    {% for obj in objects %}
        <tr>
            <td> {{ obj.id }}</td>
            <td>{{ obj.name }}</td>  <!--td标签:普通表格,内容左对齐-->
            <td>{{ obj.password }}</td>
            <td>{{ obj.age }}</td>
            <td>{{ obj.account }}</td>
            <td>{{ obj.create_time|date:"Y-m-d" }}</td>
            <td>{{ obj.get_gender_display }}</td>
            <td>{{ obj.depart.title }}</td>
            <td>
                <a class="btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a>
                <a class="btn-danger btn-ns" href="/user/{{ obj.id }}/data/">删除</a>
            </td>
        </tr>
    {% endfor %}
</table>
</body>
</html>
  •  员工添加html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div>
            <h1> 编辑用户</h1>
        </div>
        <form method="post" novalidate>
            <fieldset>
                {% csrf_token %}
                {% for iteam in form %}
                    <div class="form-group">
                        {{ iteam.label }}: {{ iteam }}<br><br>
                        <span style="color: red"> {{ iteam.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">
                    提交
                </button>
            </fieldset>
        </form>
    </div>
</div>
</body>
</html>
  •  员工注册html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div>
            <h1> 用户管理系统注册表</h1>
        </div>
        <form method="post" novalidate>
            <fieldset>
                {% csrf_token %}
                {% for iteam in form %}
                    <div class="form-group">
                        {{ iteam.label }}: {{ iteam }}<br><br>
                        <span style="color: red"> {{ iteam.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">
                    提交
                </button>
            </fieldset>
        </form>
    </div>
</div>
</body>
</html>

 以上就是该程序的所有代码,只有登陆页面加了css


总结:

以上就是本期的分享,在后续的文章中给大家说明原理,并且代码内附注释,我们下期见

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值