学习笔记-django项目-员工管理系统

一、新建项目和APP

新建文件夹staff_management

pycharm中创建新项目

终端执行 python -m venv virtual_env(虚拟环境名称) 新建虚拟环境

Windows执行 virtual_env(虚拟环境名)\Scripts\activate 激活虚拟环境

虚拟环境中 pip install django (-i https://pypi.tuna.tsinghua.edu.cn/simple) 如下载失败使用镜像源

虚拟环境执行 django-admin startproject staff_management_01(项目名) . 创建项目

执行 python manage.py migrate 创建数据库

执行 python manage.py startapp manage01(应用名称) 创建应用程序

在项目文件夹(staff_management_01)下settings.py中installed_apps中添加 manage01.apps.Mange01Config 注册应用

二、创建表结构

应用中models.py文件内根据需求设计表结构

from django.db import models

# Create your models here.


class Department(models.Model):
    """部门表结构"""
    # verbose_name:备注名称
    title = models.CharField(verbose_name='部门标题', max_length=32)


class Employee(models.Model):
    """员工表结构"""
    name = models.CharField(verbose_name='姓名', max_length=16)
    pwd = models.CharField(verbose_name='密码', max_length=64)
    age = models.IntegerField(verbose_name='年龄')
    # max_digits:数字位长度
    # decimal_places:小数位个数
    salary = models.DecimalField(verbose_name='工资', max_digits=10, decimal_places=2, default=0)
    entry_name = models.DateTimeField(verbose_name='入职时间')
    # 外键约束  to:与哪张表关联  to_field: 与表中哪列关联  on_delete: 级联删除
    depart = models.ForeignKey(to='Department', to_field='id', on_delete=models.CASCADE)
    # 置空
    # depart = models.ForeignKey(to='Department', to_field='id', null=True, blank=True, on_delete=models.SET_NULL)
    gender_choices = ((1, "男"), (2, "女"))
    # choices: 在指定范围内选择
    gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)

三、生成数据库

MySQL中执行 create database staff_management; 创建数据库

修改setting.py中的内容,连接MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'staff_management',
        'USER': 'root',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': 3306,
    }
}

通过django生成数据库表:

虚拟环境下须有pymysqlmysqlclient两个包,没有的话先安装

执行 

python manage.py makemigrations manage01(APP名称)

python manage.py migrate

四、部门列表

应用目录下新建 templatesstatic 文件夹备用

staff_management_01(项目)文件夹下urls.py文件夹中添加

from django.contrib import admin
from django.urls import path
from manage01 import views

urlpatterns = [
    path("admin/", admin.site.urls),
    path('department/list', views.depart_list)
]

manage01文件夹下views.py中添加

from django.shortcuts import render

# Create your views here.


def depart_list(request):
    """部门列表"""

    return render(request, 'department_list.html')

templates文件夹下创建department_list.html文件(暂时设计大致结构)

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</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="/department/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 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-primary" href="#">添加</a>
    </div>
    <div class="bs-example" data-example-id="panel-without-body-with-table">
    <div class="panel panel-default">
      <!-- Default panel contents -->
      <div class="panel-heading">部门列表</div>

      <!-- Table -->
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>ID</th>
            <th>部门名称</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  </div>
</div>
<script src="{% static 'js/jquery-3.7.0.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>

此时预览网页如下,但是表格内容为提前输入的,并没有从数据库获取:

从数据库获取数据并显示到网页(已提前在数据库中添加了两个数据):

1-获取数据库数据:

from django.shortcuts import render
from manage01 import models

# Create your views here.


def depart_list(request):
    """部门列表"""
    dp_list = models.Department.objects.all()

    return render(request, 'department_list.html', {"dp_list": dp_list})

2- 在网页显示数据:

<tbody>
{% for obj in dp_list %}
    <tr>
        <th scope="row">{{ 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 %}
</tbody>

完成后页面如下:

五、跳转-新建部门

左上角“新建部门”设置跳转

<a class="btn btn-primary" href="/department/add" target="_blank">
    <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
    新建部门
</a>

编写/department/add页面:

1-添加URL:

from django.contrib import admin
from django.urls import path
from manage01 import views

urlpatterns = [
    path("admin/", admin.site.urls),
    path('department/list', views.depart_list),
    path('department/add', views.depart_add),
]

2-添加views:

def depart_add(request):
    """添加部门"""

    if request.method == 'GET':
        return render(request, 'department_add.html')

3-编写department_add.html页面:

PS:HTML页面里head、js、nav部门可直接照抄department_list.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加部门</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</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="/department/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 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 class="form-horizontal" method="post">
                  {% csrf_token %}
                  <div class="form-group">
                    <label class="col-sm-2 control-label">部门名称</label>
                    <div class="col-sm-10">
                      <input type="text" class="form-control" placeholder="标题" name="depart" id="department">
                    </div>
                  </div>

                  <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                      <button type="submit" class="btn btn-primary">保存</button>
                    </div>
                  </div>
              </form>
          </div>
        </div>
    </div>
</div>

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

页面如下:

4-获取刚提交的部门名称并重定向回/department/list:

def depart_add(request):
    """添加部门"""

    if request.method == 'GET':
        return render(request, 'department_add.html')

    title = request.POST.get("depart")
    models.Department.objects.create(title=title)

    return redirect('/department/list')

六、删除部门

1-增加URL

urlpatterns = [
    path("admin/", admin.site.urls),
    path('department/list/', views.depart_list),
    path('department/add/', views.depart_add),
    path('department/delete/', views.depart_del),
]

2-修改views.py

def depart_del(request):
    """删除部门"""

    nid = request.GET.get('nid')
    models.Department.objects.filter(id=nid).delete()

    return redirect('/department/list')

在department_list.html下修改“删除”键的链接:

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

七、修改部门

添加URL:

from django.contrib import admin
from django.urls import path
from manage01 import views

urlpatterns = [
    path("admin/", admin.site.urls),
    path('department/list/', views.depart_list),
    path('department/add/', views.depart_add),
    path('department/delete/', views.depart_del),
    path('department/<int:nid>/edit', views.depart_edit),
]

编写views:

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("depart")
    models.Department.objects.filter(id=nid).update(title=title)

    return redirect("/department/list")

编写页面:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加部门</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</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="/department/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 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 class="form-horizontal" method="post">
                  {% csrf_token %}
                  <div class="form-group">
                    <label class="col-sm-2 control-label">部门名称</label>
                    <div class="col-sm-10">
                      <input type="text" class="form-control" placeholder="标题" name="depart" id="department"
                      value="{{ row_object.title }}">
                    </div>
                  </div>

                  <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                      <button type="submit" class="btn btn-primary">保存</button>
                    </div>
                  </div>
              </form>
          </div>
        </div>
    </div>
</div>

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

修改list页面:

 <a class="btn btn-primary btn-xs" href="/department/{{ obj.id }}/edit">编辑</a>

八、django中的模板复用

模板HTML中{% block 模板名称 %} {% endblock %}部分为模板外自定义内容

模板复用:

{% extends '模板.html' %}

{% block 模板名称 %}

自定义内容

{% endblock %}

九、员工列表

添加URL:

from django.contrib import admin
from django.urls import path
from manage01 import views

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

    # 部门管理
    path('department/list/', views.depart_list),
    path('department/add/', views.depart_add),
    path('department/delete/', views.depart_del),
    path('department/<int:nid>/edit', views.depart_edit),

    # 用户管理
    path('user/list', views.user_list),
]

添加views:

def user_list(request):
    """用户管理"""

    us_list = models.Employee.objects.all()

    return render(request, 'user_list.html', {"us_list": us_list})

编写HTML:

PS:注意在循环中的写法:

{% for obj in us_list %}
  <tr>
    <th scope="row">{{ obj.id }}</th>
      <td>{{ obj.name }}</td>
      <td>{{ obj.age }}</td>
      <td>{{ obj.salary }}</td>
      <td>{{ obj.entry_name|date:'Y-m-d' }}</td> # 时间日期
      <td>{{ obj.depart.title }}</td> # 获取关联表中的字段值
      <td>{{ obj.get_gender_display }}</td> # 获取字段对应的选择值
    <td>
      <a class="btn btn-primary btn-xs" href="#">编辑</a>
      <a class="btn btn-danger btn-xs" href="#">删除</a>
    </td>
  </tr>
{% endfor %}
{% extends 'layout.html' %}

{% block title%}
<title>用户列表</title>
{% endblock %}

{% block content %}
<div>
  <div class="container">
    <div style="margin-bottom: 10px">
      <a class="btn btn-primary" href="#" target="_blank">
        <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
        新建用户
      </a>
    </div>
    <div class="bs-example" data-example-id="panel-without-body-with-table">
    <div class="panel panel-default">
      <!-- Default panel contents -->
      <div class="panel-heading">用户列表</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>
          </tr>
        </thead>
        <tbody>
        {% for obj in us_list %}
          <tr>
            <th scope="row">{{ obj.id }}</th>
              <td>{{ obj.name }}</td>
              <td>{{ obj.age }}</td>
              <td>{{ obj.salary }}</td>
              <td>{{ obj.entry_name|date:'Y-m-d' }}</td>
              <td>{{ obj.depart.title }}</td>
              <td>{{ obj.get_gender_display }}</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>
  </div>
</div>
{% endblock %}

十、添加员工(使用ModelForm)

首先编写页面框架

添加URL

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

    # 部门管理
    path('department/list/', views.depart_list),
    path('department/add/', views.depart_add),
    path('department/delete/', views.depart_del),
    path('department/<int:nid>/edit', views.depart_edit),

    # 用户管理
    path('user/list', views.user_list),
    path('user/add', views.user_add),
]

添加views

需要先定义一个MyForm类,类中再定义一个Meta类,Meta类中指定了model及需要用到的字段fields  = “__all__”或给一个指定的列表,如需要的字段比较多,只有少数不需要使用,可使用exclude代替fields(同样是一个列表)

from django import forms

class MyForm(forms.ModelForm):
    class Meta:
        model = models.Employee
        fields = ['name', "pwd", "age", "salary", "entry_name", "gender", "depart"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control"}

def user_add(request):
    """添加用户"""
    form = MyForm()

    return render(request, 'user_add.html', {"form": form})

编写HTML:

与前面基本一致,只是表单部分有不同:

<div class="panel-body">
    <form method="post">
        {% csrf_token %}
            {% for field in form %}
                <div class="form-group">
                    <label class="col-sm-2 control-label">{{ field.label }}</label>
                    {{ field }}
                 </div>
             {% endfor %}

             <div class="form-group">
                 <div class="col-sm-offset-2 col-sm-10">
                     <button type="submit" class="btn btn-primary">保存</button>
                 </div>
             </div>
    </form>
</div>

完整HTML:

{% extends 'layout.html' %}

{% block title %}
<title>添加用户</title>
{% endblock %}

{% block content %}
<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 %}
                    {% for field in form %}
                  <div class="form-group">
                    <label class="col-sm-2 control-label">{{ field.label }}</label>
                      {{ field }}
                  </div>
                    {% endfor %}

                  <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                      <button type="submit" class="btn btn-primary">保存</button>
                    </div>
                  </div>
              </form>
          </div>
        </div>
    </div>
</div>
{% endblock %}

添加员工并进行验证及错误提示:

class MyForm(forms.ModelForm):
    # 默认的验证只能判断空值,自定义验证项目写法如下
    # name = forms.CharField(min_length=3, label="用户名")

    class Meta:
        model = models.Employee
        fields = ['name', "pwd", "age", "salary", "entry_name", "gender", "depart"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control"}


def user_add(request):
    """添加用户"""

    if request.method == 'GET':
        form = MyForm()
        return render(request, 'user_add.html', {"form": form})

    # 提交数据
    form = MyForm(data=request.POST)

    # 校验数据
    if form.is_valid():
        form.save()
        return redirect("/user/list")
    else:
        return render(request, 'user_add.html', {"form": form})

表单修改:

<form method="post" no validate>
    {% csrf_token %}
        {% for field in form %}
            <div class="form-group">
                <label class="col-sm-2 control-label">{{ field.label }}</label>
                    {{ field }}
                    <span style="color: red;">{{ field.errors.0 }}</span>
            </div>
        {% endfor %}

        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary">保存</button>
            </div>
        </div>
</form>

十一、编辑员工

添加URL(根据员工ID):

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

    # 部门管理
    path('department/list/', views.depart_list),
    path('department/add/', views.depart_add),
    path('department/delete/', views.depart_del),
    path('department/<int:nid>/edit', views.depart_edit),

    # 用户管理
    path('user/list', views.user_list),
    path('user/add', views.user_add),
    path('user/<int:nid>/edit', views.user_edit),
]

编写views-同样使用modelform:

def user_edit(request, nid):
    """编辑用户"""

    # 根据ID获取数据
    row_object = models.Employee.objects.filter(id=nid).first()
    
    if request.method == "GET":
        # 默认值设置: instance=row_object
        form = MyForm(instance=row_object)

        return render(request, "user_edit.html", {"form": form})

    form = MyForm(data=request.POST, instance=row_object)

    if form.is_valid():
        form.save()
        return redirect("/user/list")

    return render(request, 'user_edit.html', {"form": form})

编写HTML:

{% 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 class="col-sm-2 control-label">{{ field.label }}</label>
                      {{ field }}
                      <span style="color: red;">{{ field.errors.0 }}</span>
                  </div>
                    {% endfor %}

                  <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                      <button type="submit" class="btn btn-primary">保存</button>
                    </div>
                  </div>
              </form>
          </div>
        </div>
  </div>
{% endblock %}

十二、验证数据

方法一:

在Modelform中的fields字段中每个添加的项可以定义一个‘clean_字段名’的方法:

from django.core.exceptions import ValidationError

class MyForm(forms.ModelForm):
    class Meta:
        model = models.XXX
        fields = ["field1", "field2"]


    def clean_field1(self):
        # 获取对应字段的用户输入值
        field_1 = self.cleaned_data["field1"]
        
        # 条件判断
        if len(field_1) != 11:
            # 验证不通过
            raise ValidationError("提示信息")

        # 验证通过
        return field_1

方法二:

from django.core.validators import RegexValidator

class MyForm(forms.ModelForm):
    # 定义字段
    field1 = forms.CharField(label="xxx", validators=[RegexValidator(r'正则表达式', '错误提示信息')])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值