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

在上一章中介绍了如何配置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部分,未完待续,请持续关注这个系列。

猜你喜欢

转载自blog.csdn.net/Faith_cxz/article/details/128533955