Django开发员工管理系统(Part I)

news2024/9/24 15:24:47

文章目录

  • 1. 准备工作
    • 1.1 创建django项目
    • 1.2 创建app
    • 1.3 配置settings.py文件,完成app注册
  • 2. 设计数据库表结构
  • 3. 在MySQL中生成表
    • 3.1 创建数据库
    • 3.2 修改配置文件,连接MySQL数据库
    • 3.3 通过django命令生成数据库表
  • 4. 编写部门列表
    • 4.1 (前段页面)准备工作
      • 4.1.1 jQuery
      • 4.1.2 bootstrap
    • 4.2 编写前段代码
    • 4.3 实现部门具体功能
      • 4.3.1 查找数据库
      • 4.3.2 新增部门
      • 4.3.3 删除部门
      • 4.3.4 修改部门
  • 5. 模板的继承
  • 6. 实现员工具体功能
    • 6.1 查找数据库
    • 6.2 新增员工
  • 7. ModelForm的使用
  • 8. 总结

在上一章中介绍了如何配置Django框架等以及一些注意细节,俗话说:“配置好项目的环境相当于完成了整个项目的80%”,如果还有没配好Django框架的,可以先看看前面的这篇文章:走进Django框架。

1. 准备工作

1.1 创建django项目

  • 管理员模式打开cmd。
  • 使用cd命令定位到要保存项目的文件夹。eg:cd py_code\PycharmProjects。
  • 输入django-admin startproject 创建项目名称 的格式就可以创建出django项目。eg: django-admin startproject mysite。

1.2 创建app

在pycharm终端进行添加app(功能模块),输入格式:python manage.py startapp app名称。eg:python manage.py startapp webapp

1.3 配置settings.py文件,完成app注册

请添加图片描述

2. 设计数据库表结构

在这个项目中我们可以包含的表有:部门表和员工表。

  • 在部门表中我们需要有部门的名称和部门的ID,而其中的ID我们是可以直接使用django中创建表里面的自增ID的,所以部门表的这个类我们就可以这样写:

    •   class Department(models.Model):
            """ 部门表 """
            title = models.CharField(verbose_name="标题", max_length=32)
      
  • 在员工表中我们则需要员工的名字、密码、年龄、账户余额、创建时间等(这些都是普通正常创建即可)。

    •   	name = models.CharField(verbose_name="姓名", max_length=16)
            password = models.CharField(verbose_name="密码", max_length=64)
            age = models.IntegerField(verbose_name="年龄")
            accout = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
            create_time = models.DateTimeField(verbose_name="创建时间")
      
  • 员工表中还可以有员工性别,这时候我们可以使用django中的约束,将1代表成男,2代表成女,即可以写成下面这样:

    •       gender_choices = (
                (1, "男"),
                (2, "女"),
            )
            gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
      
  • 除此之外,员工表中还必须有员工对应的部门,我们这里使用的是django自动约束,将其与上面的部门表关联起来,具体的写法是这样的:

    •       # django自动约束
            # to表示与哪张表关联 to_field表示与表中的哪一列关联
            # 此处写的depart其实django会自动生成数据列depart_id
            # 部门表删除的两种解决方案
            # 1.级联删除
            depart = models.ForeignKey(to="Department", to_field="id")
      
  • 但是上面这样写又有一点缺陷,那就是在删除部门表中的某一个部门(某一列)之后,员工表中的某一些员工上的depart_id可能就会在父表(部门表)中查找不到,而这里有两种常见的解决方法:1. 级联删除:当父表中的一条记录被删除,子表中关联的记录也会对应的自己主动删除;2. 置空处理:当父表中的一条记录被删除后,子表中关联的记录的那一列会自动置为空值。

    •       # 1.级联删除
            depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
            # 2.置空
            depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)
      

最终在models.py文件中写出来的全部代码如下:

class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name="标题", max_length=32)

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="年龄")
    gender_choices = (
        (1, "男"),
        (2, "女"),
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
    accout = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
    create_time = models.DateTimeField(verbose_name="创建时间")
    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)

3. 在MySQL中生成表

3.1 创建数据库

输入:create database employeeManagement_system default charset utf8 collate utf8_general_ci;

3.2 修改配置文件,连接MySQL数据库

由于django默认使用的数据库是sqlite,而我们现在使用的是MySQL数据库,所以我们就需要在settings.py文件里面修改一下配置。

注释掉原来的DATABASES,修改成下面这一段:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'employeeManagement_system', # 刚才创建数据库的名字
        'USER': 'root',
        'PASSWORD': '123456', # 自己数据库的密码
        'HOST': '127.0.0.1', # 安装MySQL的机器(默认这里都是主机安装)
        'PORT': '3306', # 设置端口号(默认3306)
    }
}

3.3 通过django命令生成数据库表

在pycharm终端输入命令(依次输入):

python manage.py makemigrations
python manage.py migrate

之后在MySQL之后查看验证有这两个表即说明生成成功:

请添加图片描述

4. 编写部门列表

对于一些前段的样式,这里推荐一个网站:https://v3.bootcss.com/components。

4.1 (前段页面)准备工作

在编写前段页面之前需要导入两样东西:jQuery和bootstrap。

4.1.1 jQuery

在浏览器打开网页:https://code.jquery.com/jquery-3.6.0.min.js,Ctrl+s将整个文件下载下来。将下载下来的整个文件放在static下的js文件夹中。

请添加图片描述

4.1.2 bootstrap

在浏览器打开网页:https://v3.bootcss.com/getting-started/#download,下载用于生产环境的 Bootstrap。将下载下来的整个文件夹放在static下的plugins文件夹中。

请添加图片描述

4.2 编写前段代码

本系列注重的是django开发,因此前端代码直接给出。

{% load static %}
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <style>
      .navbar{
        border-radius: 0;
      }
    </style>
</head>
<body>
<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><a href="/depart/list/">部门管理</a></li>
        <li><a href="#">Link</a></li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <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>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

<div>
  <div class="container">
    <div style="margin-bottom: 10px">
      <a class="btn btn-success" href="#">
        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
        新建部门
      </a>
    </div>
    
    <div class="panel panel-default">
      <!-- Default panel contents -->
      <div class="panel-heading">
        <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
        部门列表
      </div>

      <!-- Table -->
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>ID</th>
            <th>部门名称</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th>1</th>
            <td>销售部</td>
            <td>
              <a class="btn btn-primary btn-xs">编辑</a>
              <a class="btn btn-danger btn-xs">删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

  </div>
</div>

<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

页面显示:

请添加图片描述

4.3 实现部门具体功能

4.3.1 查找数据库

请添加图片描述

当数据库中有数据的时候,我们就需要将这些数据加载到页面上,这对应到上一章中总结的django对表中数据的查操作。

# 去数据库中获取所有部门列表(查)
    data_list = models.Department.objects.all()

    return render(request, 'depart_list.html', {'data_list': data_list})

在前端代码中进行遍历显示。

{% for obj in data_list %}
            <tr>
              <th>{{ obj.id }}</th>
              <td>{{ obj.title }}</td>
              <td>
                <a class="btn btn-primary btn-xs">编辑</a>
                <a class="btn btn-danger btn-xs">删除</a>
              </td>
            </tr>
          {% endfor %}

请添加图片描述

4.3.2 新增部门

前端页面:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新建部门</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <style>
      .navbar{
        border-radius: 0;
      }
    </style>
</head>
<body>
    <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><a href="/depart/list/">部门管理</a></li>
              <li><a href="#">Link</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
              <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>
                </ul>
              </li>
            </ul>
          </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
      </nav>
    
    <div>
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                  <h3 class="panel-title">新建部门</h3>
                </div>
                <div class="panel-body">
                    <form method="post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label>部门名称</label>
                            <input type="text" class="form-control" placeholder="部门名称" name="title" />
                        </div>
                        <button type="submit" class="btn btn-primary">保 存</button>
                      </form>
                </div>
              </div>
        </div>
    </div>
    
    <script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
    <script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

逻辑代码:显示页面是get请求,提交操作是post请求。

def depart_add(request):
    """添加部门"""
    if request.method == 'GET':
        return render(request, 'depart_add.html')
    title = request.POST.get("title")
    models.Department.objects.create(title=title)
    return redirect("/depart/list/")

4.3.3 删除部门

删除功能是比较简单的,通过id来删除数据库中的数据。

前端代码:

<a class="btn btn-danger btn-xs" href="/depart/delete/?nid={{ obj.id }}">删除</a>

逻辑代码:

def depart_delete(request):
    """ 删除部门 """
    nid = request.GET.get('nid')
    models.Department.objects.filter(id=nid).delete()
    return redirect("/depart/list/")

4.3.4 修改部门

在url中我们可以使用正则表达式的形式来编写,以后获取id也是通过这里的nid进行获取的:path('depart/<int:nid>/edit/', views.depart_edit)

前端代码:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新建部门</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <style>
      .navbar{
        border-radius: 0;
      }
    </style>
</head>
<body>
    <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><a href="/depart/list/">部门管理</a></li>
              <li><a href="#">Link</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
              <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>
                </ul>
              </li>
            </ul>
          </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
      </nav>
    
    <div>
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                  <h3 class="panel-title">修改部门</h3>
                </div>
                <div class="panel-body">
                    <form method="post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label>部门名称</label>
                            <input type="text" class="form-control" placeholder="部门名称" name="title" value="{{ row_object.title }}" />
                        </div>
                        <button type="submit" class="btn btn-primary">保 存</button>
                      </form>
                </div>
              </div>
        </div>
    </div>
    
    <script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
    <script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>

逻辑代码:

def depart_edit(request, nid):
    """ 修改部门 """
    if request.method == "GET":
        row_object = models.Department.objects.filter(id=nid).first()
        return render(request, 'depart_edit.html', {"row_object": row_object})
    title = request.POST.get("title")
    models.Department.objects.filter(id=nid).update(title=title)
    return redirect("/depart/list/")

5. 模板的继承

在上面的前段代码中会发现一个问题:模板的重复性非常高,那么我们可以对这些模板进行提取吗?

答案是可以的。在django中是支持模板继承的,格式如下:

在模板的前面写上众多模板的共同点...

    <div>
        {% block content %}{% endblock %}
    </div>
    
在模板的后面写上众多模板的共同点...

注意:中间的{% block content %}{% endblock %}就是继承模板中不一样的部分,只需要在继承模板中写下这个骨架:

{% extends 'layout.html' %}
{% block content %}
	...
{% endblock %}

在骨架的中间(省略号部分)写下每一个继承模板独有的点即可,其他前面或者后面部分的内容都会去被继承的模板中调用。

6. 实现员工具体功能

6.1 查找数据库

先在员工表中添加一行数据:

请添加图片描述

前段代码:这里使用模板继承。

{% extends 'layout.html' %}

{% block content %}
<div class="container">
  <div style="margin-bottom: 10px">
    <a class="btn btn-success" href="#">
      <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
      新增员工
    </a>
  </div>
  
  <div class="panel panel-default">
    <!-- Default panel contents -->
    <div class="panel-heading">
      <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
      员工列表
    </div>

    <!-- Table -->
    <table class="table table-bordered">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>密码</th>
          <th>年龄</th>
          <th>账户余额</th>
          <th>入职时间</th>
          <th>性别</th>
          <th>所属部门</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        {% for obj in data_list %}
          <tr>
            <th>{{ obj.id }}</th>
            <td>{{ obj.name }}</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 btn-primary btn-xs" href="#">编辑</a>
              <a class="btn btn-danger btn-xs" href="#">删除</a>
            </td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
</div>
{% endblock %}

注意:时间转字符串的模板语法(eg:obj.create_time|date:"Y-m-d")、django自动连表操作(eg:obj.depart.title)、django选择约束获取的操作(eg:obj.get_gender_display)。

逻辑代码:

def user_list(request):
    """ 用户列表 """
    data_list = models.UserInfo.objects.all()
    return render(request, 'user_list.html', {"data_list": data_list})

6.2 新增员工

前段代码:

{% extends 'layout.html' %}

{% block content %}
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">新建员工</h3>
        </div>
        <div class="panel-body">
            <form method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label>姓名</label>
                    <input type="text" class="form-control" placeholder="姓名" name="name" />
                </div>
                <div class="form-group">
                    <label>密码</label>
                    <input type="text" class="form-control" placeholder="密码" name="password" />
                </div>
                <div class="form-group">
                    <label>年龄</label>
                    <input type="text" class="form-control" placeholder="年龄" name="age" />
                </div>
                <div class="form-group">
                    <label>账户余额</label>
                    <input type="text" class="form-control" placeholder="账户余额" name="account" />
                </div>
                <div class="form-group">
                    <label>入职时间</label>
                    <input type="text" class="form-control" placeholder="入职时间" name="create_time" />
                </div>
                <div class="form-group">
                    <label>性别</label>
                    <select class="form-control" name="gender">
                        {% for item in gender_choices %}
                            <option value="{{ item.0 }}">{{ item.1 }}</option>
                        {% endfor %}
                    </select>
                </div>
                <div class="form-group">
                    <label>所属部门</label>
                    <select class="form-control" name="depart">
                        {% for item in depart_list %}
                            <option value="{{ item.id }}">{{ item.title }}</option>
                        {% endfor %}
                    </select>
                </div>
                <button type="submit" class="btn btn-primary">保 存</button>
              </form>
        </div>
      </div>
</div>
{% endblock %}

逻辑代码:

def user_add(request):
    """ 添加用户 """
    if request.method == 'GET':
        context = {
            'gender_choices': models.UserInfo.gender_choices,
            'depart_list': models.Department.objects.all()
        }
        return render(request, 'user_add.html', context)
    name = request.POST.get('name')
    password = request.POST.get('password')
    age = request.POST.get('age')
    account = request.POST.get('account')
    create_time = request.POST.get('create_time')
    gender = request.POST.get('gender')
    depart_id = request.POST.get('depart')
    models.UserInfo.objects.create(name=name,password=password,age=age,
                                   account=account,create_time=create_time,
                                   gender=gender,depart_id=depart_id)
    return redirect("/user/list/")

7. ModelForm的使用

我们在上面进行员工信息录入的时候采用的是最原始的方法,虽然也是可以解决问题,但是代码总体看起来是非常臃肿的,当输入框需要再增加或者减少的时候,势必就会进行一系列的改动,对此,django中就引入了ModelForm插件,这也是比较主流的开发方式,减少了很多工作量。

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

在view.py中写下这类就表示在这个类下引入django中的ModelForm插件,而model = models.UserInfo表示的就是使用models.py的哪个类(这里使用的是员工类),后面写下:fields = ["name","password","age","account","create_time","gender","depart"]表示的就是django会自动帮我们生成这些字段,将这个封装上字段的类传到前端,使用一个简单的循环就可以实现之前普通写法中页面一样的显示功能:

{% for field in form %}
	<div class="form-group">
		<label>{{ field.label }}</label>
		{{ field }}
	</div>
{% endfor %}

前提是需要导入forms包:from django import forms

除此之外,我们还需要在类中定义一个函数(这个函数一定是固定的),在函数中循环使用widget插件,通过这个插件中的attrs就可以指定前段代码的class样式或者placeholder等等。

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control", "placeholder": field.label}

这时候会发现一个问题,就是所属部门的下拉框中显示的不是一个一个的部门名称,而是一些类对象,这是因为django中通过部门id去找部门之后返回的形式是去调用__str__函数的,而这个函数默认的返回值就事当前对象,这里我们就需要自己重新写一个__str__函数,并且重新指定其返回值。

class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name="标题", max_length=32)
    def __str__(self):
        return self.title

以上就可以把整个添加页面很好地显示出来了(总体上与之前写的页面并无区别,但是引入了ModelForm插件使得代码量少了不少,代码的复用程度也提高了)。接下来就是提交数据的功能,在使用插件的情况下,我们提交数据的时候还可以对数据进行校验,如果数据合法就可以存到数据库中,若有数据不合法的情况的话,就会在当前页面上显示错误。

比如django中支持可以直接在引入插件的类中对提交的出入进行一个限制(下面这样就表示了密码只能够是大于6位数的),并且在django中如果不做限制,默认的就是非空,也就是说如果有空没填的话也是会显示错误信息的。

password = forms.CharField(min_length=6, label="密码")

还有一点是数据不合法的时候页面中显示的错误信息是英文的,为了方便用户,我们可以手动在settings.py文件中修改显示语言配置:

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'

将原来的en-us注释掉,修改成zh-hans。

其他的具体看总的代码即可:

前段代码:

{% extends 'layout.html' %}

{% block content %}
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">新建员工</h3>
        </div>
        <div class="panel-body">
            <form method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">
                        <label>{{ field.label }}</label>
                        {{ field }}
                        <span style="color: red;">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-primary">保 存</button>
              </form>
        </div>
      </div>
</div>
{% endblock %}

逻辑代码:

# 编写ModelFrom类
class UserModelForm(forms.ModelForm):
    password = forms.CharField(min_length=6, label="密码")
    class Meta:
        model = models.UserInfo
        fields = ["name","password","age","account","create_time","gender","depart"]
        # widgets = {
        #     "name": forms.TextInput(attrs={"class": "form-control"})
        # }
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control", "placeholder": field.label} # 循环找到所有插件,添加"class": "form-control"
def user_model_form_add(request):
    """ 添加用户(ModelFrom版) """
    if request.method == 'GET':
        form = UserModelForm()
        return render(request, 'user_model_form_add.html', {"form": form})
    # 进行数据校验
    form = UserModelForm(data=request.POST)
    if form.is_valid():
        # 如果数据合法。加入到数据库中
        form.save()
        return redirect('/user/list/')
    # 在页面上显示错误信息
    return render(request, 'user_model_form_add.html', {"form": form})

8. 总结

以上为Django开发员工管理系统的Part I部分,未完待续,请持续关注这个系列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/137463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

报表开发工具FastReport.NET的十大常见问题及解决方法(二)

Fastreport是目前世界上主流的图表控件&#xff0c;具有超高性价比&#xff0c;以更具成本优势的价格&#xff0c;便能提供功能齐全的报表解决方案&#xff0c;连续三年蝉联全球文档创建组件和库的“ Top 50 Publishers”奖。慧都科技是Fast Reports在中国区十余年的友好合作伙…

php宝塔搭建部署实战海洋cms视频内容管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套php开发的海洋cms视频内容管理系统源码&#xff0c;感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&#…

在动态规划的海洋中遨游(一)

前言&#xff1a;\textcolor{Green}{前言&#xff1a;}前言&#xff1a; &#x1f49e;本专栏用于本人刷算法的过程。主要包含刷题中的感受以及知识点缺陷。对于学习者来说可以作为参考。 目前更新的算法内容会比较多&#xff0c;很多都是通过刷题来进行知识点的总结&#xff0…

计算机SCI论文,很难发表吗?应该如何发表? - 易智编译EaseEditing

首先&#xff0c;找题目需要符合国际标准&#xff0c;但不要缺少创新的探究题目。这个题目可以是最新的技术&#xff0c;也可以是最新的领域&#xff1b; 也可以是探索过很多次的课题。但是如果我们想成功交付&#xff0c;如何创新是我们需要思考的。 其次&#xff0c;因为英语…

为什么有的电源不是从0V开始上电的

大家可以看下&#xff0c;这张图片是测试XILINX 的FPGA 325T的上电时序图&#xff0c;其中绿色的线是FPGA 核心电源VCCINT 1.0V的波形&#xff0c;黄色的是BANK的电源2.5V的波形&#xff0c;蓝色的是辅助电源1.8V 的波形大家有没有发现这个时序图中黄色的波形&#xff0c;也就是…

Java之多线程详解

目录 一、线程简介 进程&#xff08;Process &#xff09;与 线程&#xff08;Thread&#xff09; 二、线程创建 1、线程Thread 1.1. 步骤 1.2 应用 1.3 案例&#xff1a;下载图片 2、实现Runnable接口 2.1 步骤 2.2 应用 3.小结 3. 实现Callable接口&#xff08;了解…

java开发的考研系统大学生考研推荐网站考研网站源码

简介&#xff1a; 考研信息推荐查询。主要是管理发布管理考研的知识文章&#xff0c;或者上传资料&#xff0c;发布考研的视频。学生可以注册后下载资料&#xff0c;查看考研文章视频等。文章分为vip文章和普通文章&#xff0c;学生查看vip文章需要消耗积分。 演示视频 https…

FX5U 原点回归指令 DSZR

上一篇文章中转述了网友的文章&#xff0c;因回原点实在重要&#xff0c;再详细描述DSZR指令。 DSZR是具有自动搜索功能的原点回归指令。它对当前位置没有要求&#xff0c;在任意位置哪怕是停止在限位开关位置上都能完成原点回归操作。 1.指令格式 S1 原点回归速度或存储了数…

linux虚拟机搭建kafka(单节点、使用kafka自带zookeeper)

本文使用kafka单节点安装及配置&#xff0c;并使用kafka自带的zookeeper。一般kafka需要起三个kafka构成集群&#xff0c;可以连单独的zookeeper&#xff0c;本文不涉及。一、kafka下载解压安装包下载地址&#xff1a;https://archive.apache.org/dist/kafka/2.5.0/kafka_2.12-…

MyPerf4J结合Grafana和InfluxDB采集JVM以及QPS指标

MyPerf4J结合Grafana和InfluxDB采集JVM以及QPS指标 背景 ​ 需要采集现场java程序运行的状态数据(包括JVM指标以及QPS,RPS指标等)。需要采集的方式尽可能轻量化 ​ 结合实际情况采用MyPerf4J作为Java探针&#xff0c;InfluxDB作为数据存储端&#xff0c;Grafana作为数据展示…

15---整合Echarts和完善头像上传

1、完善头像上传功能 上次写的头像上传功能&#xff0c;不能实现上传保存后立刻刷新右上角头像&#xff0c;这里做一个完善。首先是在Manage.vue中&#xff08;父&#xff09;&#xff0c;写刷新User的方法 //传一个user过去到header <Header :collapseBtnClass"col…

【信息论与编码 沈连丰】第三章:离散信源

【信息论与编码 沈连丰】第三章&#xff1a;离散信源第三章 离散信源3.1 离散信源的分类及其描述3.2 离散信源的熵3.3 信源的冗余度3.4 信源符号序列分组定理3.5 平稳离散信源及其性质第三章 离散信源 3.1 离散信源的分类及其描述 信源分类&#xff1a;本质上主要基于两方面来…

fastai教程学习笔记

这几天对着fastai教程读了下&#xff0c;大部分写得已经很不错。这里做点知识精炼的笔记。 安装fastai 推荐在conda环境内执行以下命令。它 pip install fastaifastai架构 fastai的编程架构如下图所示&#xff1a; fastai提供了高、中、低三层的API&#xff0c;用户可以根…

73、【哈希表】leetcode——15. 三数之和(C++版本)

题目描述 原题链接&#xff1a;15. 三数之和 解题思路 本题的难点在于去重&#xff0c;针对两种不同的方式&#xff1a;双指针和Hash采用不同的去重判定条件。 1、去重的目标 要明确&#xff0c;去重的是重复三元组&#xff0c;而不是三元组里重复的数。 2、去重初步思路 …

商业与数据生态议题解读,Doris Summit 2022 分论坛议程介绍|即刻报名

Doris Summit 2022 将于1 月 6 -7 日在线上正式举办&#xff0c;本次峰会共分2 天进行&#xff0c;首日上午为主论坛&#xff1a;核心技术解析&#xff0c;下午为商业与数据生态分论坛&#xff0c;7 日全天为行业用户最佳实践案例。大会汇聚了来自全球顶尖云厂商、一线互联网企…

CoMER论文翻译

文章目录Abstract1、Introduction2、Related Work2.1 HMER Methods2.2 Coverage Mechanism3、Methodology3.1、Background3.2、CNN Encoder3.3、Positional Encoding3.4、Attention Refinement Module3.5、Coverage4 Experiments论文链接&#xff1a;https://arxiv.org/abs/220…

数字图像处理 图像对比度增强算法概览

一、图像对比度增强 图像对比度增强又叫作图像对比度拉伸或者直接称为点运算。图像亮度和对比度调整的目的之一是在合适的亮度上提供最大的细节信息&#xff0c;细节纹理的沟纹越深&#xff0c;图像越清晰。在图像处理中&#xff0c;图像对比度增强是最基本的、原理比较简单却很…

【前端】Vuex模块化和持久化应用示例

概述 Vuex作为VUE状态管理组件&#xff0c;能够将项目公共数据进行统一管理。而且可以按照不同的业务功能将数据状态分模块管理。另外&#xff0c;对于网页刷新导致Vuex状态丢失的问题可以使用vuex-persistedstate插件配置将数据保存在localStorage或者sessionStorage中。 本…

「Python|场景案例」如何给图片添加水印

本文主要介绍如何使用python的PIL库给图片增加水印 文章目录背景说明工具准备处理步骤源代码处理效果展示背景说明 当我们想给一些图片添加水印的时候&#xff0c;尤其是图片数量较多的时候&#xff0c;就可以使用python进行自动化处理。包括但不限于在自媒体上发布自己的各种…

如何使用自助式商业智能 (BI) 避免组织中的数据孤岛

许多组织都存在数据问题。当许多员工远程工作&#xff08;或在混合环境中&#xff09;并在多个位置使用多个设备访问公司数据时&#xff0c;他们正在处理信息过载问题。这只会加剧数据孤岛的问题。 数据孤岛正是它听起来的样子&#xff1a;孤立在一个孤立的用户/环境中的数据&…