【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)

目录

  • 0. 项目最终效果
  • 1. pythoncharm创建并修改项目
    • 1.1 创建项目
    • 1.2 修改项目
  • 2.创建并注册app
    • 2.1 创建app
    • 2.2 注册app
  • 3. 创建并连接数据库
    • 3.1 手动创建数据库
    • 3.2 django中连接数据库
  • 4. 数据表设计
    • 4.1 写入数据表ORM语句
    • 4.2 ORM语句生效
  • 5. 静态文件管理
  • 6. 页面编写
    • 6.1 html页面设计
      • 6.1.1 layout.html 公共导航栏
      • 6.1.2 depart_list.html 部门展示
      • 6.1.3 depart_add.html 部门添加
      • 6.1.4 depart_edit.html 部门修改
      • 6.1.5 user_list.html 用户展示
      • 6.1.6 user_add.html 用户添加
      • 6.1.7 user_model_form_add.html 用户model表单添加
    • 6.2 url.py路由写入
    • 6.3 view.py后端编写
    • 总结


欢迎关注 『Django 网页Web开发』 系列,持续更新中
欢迎关注 『Django 网页Web开发』 系列,持续更新中

0. 项目最终效果

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第1张图片

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第2张图片
【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第3张图片


1. pythoncharm创建并修改项目

1.1 创建项目

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第4张图片

1.2 修改项目

删除无用的templates文件夹,修改setting.py的dir配置
【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第5张图片


2.创建并注册app

2.1 创建app

python manage.py startapp app01

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第6张图片
使用工具可以只用输入startapp app01
【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第7张图片

2.2 注册app

修改setting.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config'
]

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第8张图片


3. 创建并连接数据库

3.1 手动创建数据库

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第9张图片

3.2 django中连接数据库

在项目的setting.py中修改数据库配置DATABASES

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # 驱动
        'NAME': 'day16',  # 数据库名字
        'USER': 'root',  # mysql用户名
        'PASSWORD': '123456',  # mysql密码
        'HOST': '127.0.0.1',  # 本机安装了MySQL
        'PORT': 3306,  # 端口
    }
}

4. 数据表设计

4.1 写入数据表ORM语句

  • 部门表
    【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第10张图片

  • 员工表
    【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第11张图片

  • app01的moudle.py

from django.db import models


class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name='标题', max_length=32)#verbose_name表示注解
    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)
    #max_digits:总位数(不包括小数点和符号)
    #decimal_places:小数位数。
    # 如:要保存最大值为 100 (小数点后保存2位)
    #你要这样定义字段:models.FloatField(…,max_digits=4, decimal_places=2)  小数点前2位+小数点后2位=4位
    create_time = models.DateTimeField(verbose_name="入职时间")

    # 无约束
    # depart_id = models.BigIntegerField(verbose_name="部门ID")
    # 1.有约束
    #   - to,与那张表关联
    #   - to_field,表中的那一列关联
    # 2.django自动
    #   - 写的depart
    #   - 生成数据列 depart_id
    # 3.部门表被删除
    # ### 3.1 级联删除,外键一并删除
    depart = models.ForeignKey(verbose_name="部门", to="Department", to_field="id", on_delete=models.CASCADE)
    # ### 3.2 置空,外键置空但是要求可以为空
    # depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)

    # 在django中做的约束
    gender_choices = (
        (1, "男"),
        (2, "女"),
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

4.2 ORM语句生效

项目根目录cmd

python manage.py makemigrations
python manage.py migrate

或者使用pycharm的manage工具

makemigrations
migrate

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第12张图片

  • 生成后的结果
    【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第13张图片

5. 静态文件管理

  • app01下创建static文件夹,放入所需要的css png js 插件等文件
  • app01下创建templates文件夹, 放入所需要的html模板文件
    【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第14张图片
{% load static %}
{#先load得到static路径然后, 导入jquery和bootstrap,注意要先导入js再导入jquery,顺序的问题#}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<script src="{% static 'js/jquery-3.6.0.min.js' %}">script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}">script>

6. 页面编写

6.1 html页面设计

没有了解过模板继承的可以看前面的文章
【Django 网页Web开发】06. 模板继承的主题导航栏案例 高效开发 便捷维护(保姆级图文)

首先确定我们的页面框架。
问几个问题:

  1. 是不是每个html页面都需要写一遍调用js和插件的代码?
  2. 页面有没有公共部分可能需要代码复用?
  3. 我们是不是需要一个标题导航栏部分?
    解决办法:
  • 建立一个公共的标题导航栏页面layout.html,写入每个页面都需要调用的静态文件,其他页面只需要调用这个公共的页面作为自身的一部分即可。既能代码复用也能创造出一片公共区域。

  • 其他页面调用公共页面的方法,实现模板继承,其他页面的编写内容只是模板的block content部分的内容

  • 模板页面尾部添加

<div>
    {% block content %}{% endblock %}
div>
  • 子页面头部添加
{% extends 'layout.html' %}
  • 子页面尾部添加
{% endblock %}

我们需要实现对于部门和用户的管理,大体上是增删改查这几个操作,需要响应的页面。其中删除就简单一点,不需要特殊的页面展示,实际上只需要展示页面,增加页面,修改页面即可。

6.1.1 layout.html 公共导航栏

bootstrap3中文文档组件的导航条示例代码基础上修改得到
https://v3.bootcss.com/components/#navbar

【Django 网页Web开发】08. 实战项目:部门和员工管理系统(01)(保姆级图文)_第15张图片

{% load static %}
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .navbar {
            border-radius: 0;
        }
    style>
head>
<body>
<nav class="navbar navbar-default">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigationspan>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
                <span class="icon-bar">span>
            button>
            <a class="navbar-brand" href="/depart/list/"> XX公司用户管理系统 a>
        div>
        <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="/user/list/">用户管理a>li>
                <li><a href="#">Linka>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">mzh <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>
    div>
nav>

<div>
    {% block content %}{% endblock %}
div>

{#导入jquery和bootstrap,注意要先导入js再导入jquery,顺序的问题#}
<script src="{% static 'js/jquery-3.6.0.min.js' %}">script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}">script>
body>
html>

6.1.2 depart_list.html 部门展示

{% extends 'layout.html' %}
{#调用模板页面layout.html,这一部分页面是公共的,这样实现了代码复用#}
{% block content %}
    <div class="container">
        <div style="margin-bottom: 10px">
            <a class="btn btn-success" href="/depart/add/">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
                新建部门
            a>
        div>
        <div class="panel panel-default">
            
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true">span>
                部门列表
            div>

            
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>IDth>
                    <th>名称th>
                    <th>操作th>
                tr>
                thead>
                <tbody>
                {% for obj in queryset %}
                    <tr>
                        <th>{{ obj.id }}th>
                        <td>{{ obj.title }}td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/depart/{{ obj.id }}/edit/">编辑a>
                            <a class="btn btn-danger btn-xs" href="/depart/delete/?nid={{ obj.id }}">删除a>
                        td>
                    tr>
                {% endfor %}
                tbody>
            table>
        div>
    div>
{% endblock %}

6.1.3 depart_add.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">
                    {% 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>
{% endblock %}

6.1.4 depart_edit.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">
                    {% 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>
{% endblock %}



6.1.5 user_list.html 用户展示

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <div style="margin-bottom: 10px">
            <a class="btn btn-success" href="/user/add/">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
                新建用户
            a>

            <a class="btn btn-success" href="/user/model/form/add/">
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
                新建用户ModelForm
            a>
        div>
        <div class="panel panel-default">
            
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true">span>
                用户列表
            div>

            
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>IDth>
                    <th>姓名th>
                    <th>密码th>
                    <th>年龄th>
                    <th>余额th>
                    <th>入职时间th>
                    <th>性别th>
                    <th>所属部门th>
                    <th>操作th>
                tr>
                thead>
                <tbody>
                {% for obj in queryset %}
                    <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 %}

6.1.6 user_add.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">
                    {% csrf_token %}

                    <div class="form-group">
                        <label>姓名label>
                        <input type="text" class="form-control" placeholder="姓名" name="user" />
                    div>

                    <div class="form-group">
                        <label>密码label>
                        <input type="text" class="form-control" placeholder="密码" name="pwd"/>
                    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="ac"/>
                    div>


                    <div class="form-group">
                        <label>入职时间label>
                        <input type="text" class="form-control" placeholder="入职时间" name="ctime"/>
                    div>

                    <div class="form-group">
                        <label>性别label>
                        <select class="form-control" name="gd">
                            {% 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="dp">
                            {% 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 %}

6.1.7 user_model_form_add.html 用户model表单添加

如果不了解相关内容,可以看前文
【Django 网页Web开发】07. 快捷的表单生成 Form与MoudleForm(保姆级图文)

{% 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 %}

6.2 url.py路由写入

注意这里的app01标红正常不影响

from django.urls import path

from app01 import views

urlpatterns = [
    path('depart/list/', views.depart_list),  # 部门列表
    path('depart/add/', views.depart_add),  # 部门添加
    path('depart/delete/', views.depart_delete),  # 部门删除
    path('depart//edit/', views.depart_edit),  # 部门编辑

    path('user/list/', views.user_list),  # 用户列表
    path('user/add/', views.user_add),  # 用户添加

    path('user/model/form/add/', views.user_model_form_add),  # 添加用户(ModelForm版本)

]

6.3 view.py后端编写

新建用户:

  • 原始方式理思路:不会采用(本质)【麻烦】

    - 用户提交数据没有校验。
    - 错误,页面上应该有错误提示。
    - 页面上,没一个字段都需要我们重新写一遍。     [OK]
    - 关联的数据,手动去获取并展示循环展示在页面。  [OK]
    
  • Django组件(集成了前人大佬们的智慧)

    • Form组件(小简便)
    • ModelForm组件(最简便)
from django.shortcuts import render, redirect
from app01 import models


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

    # 去数据库中获取所有的部门列表
    #  [对象,对象,对象]
    queryset = models.Department.objects.all()

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


def depart_add(request):
    """ 添加部门 """
    if request.method == "GET":
        return render(request, 'depart_add.html')

    # 获取用户POST提交过来的数据(title输入为空)
    title = request.POST.get("title")

    # 保存到数据库
    models.Department.objects.create(title=title)

    # 重定向回部门列表
    return redirect("/depart/list/")


def depart_delete(request):
    """ 删除部门 """
    # 获取ID http://127.0.0.1:8000/depart/delete/?nid=1
    nid = request.GET.get('nid')

    # 删除
    models.Department.objects.filter(id=nid).delete()

    # 重定向回部门列表
    return redirect("/depart/list/")


def depart_edit(request, nid):
    """ 修改部门 """
    if request.method == "GET":
        # 根据nid,获取他的数据 [obj,]
        row_object = models.Department.objects.filter(id=nid).first()
        return render(request, 'depart_edit.html', {"row_object": row_object})

    # 获取用户提交的标题
    title = request.POST.get("title")

    # 根据ID找到数据库中的数据并进行更新
    # models.Department.objects.filter(id=nid).update(title=title,其他=123)
    models.Department.objects.filter(id=nid).update(title=title)

    # 重定向回部门列表
    return redirect("/depart/list/")


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

    # 获取所有用户列表 [obj,obj,obj]
    queryset = models.UserInfo.objects.all()
    """
    # 用Python的语法获取数据
    for obj in queryset:
        print(obj.id, obj.name, obj.account, obj.create_time.strftime("%Y-%m-%d"), obj.gender, obj.get_gender_display(), obj.depart_id, obj.depart.title)
        # print(obj.name, obj.depart_id)
        # obj.depart_id  # 获取数据库中存储的那个字段值
        # obj.depart.title  # 根据id自动去关联的表中获取哪一行数据depart对象。
    """
    return render(request, 'user_list.html', {"queryset": queryset})


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)

    # 获取用户提交的数据
    user = request.POST.get('user')
    pwd = request.POST.get('pwd')
    age = request.POST.get('age')
    account = request.POST.get('ac')
    ctime = request.POST.get('ctime')
    gender = request.POST.get('gd')
    depart_id = request.POST.get('dp')

    # 添加到数据库中
    models.UserInfo.objects.create(name=user, password=pwd, age=age,
                                   account=account, create_time=ctime,
                                   gender=gender, depart_id=depart_id)

    # 返回到用户列表页面
    return redirect("/user/list/")


# ################################# ModelForm 示例 #################################
from django import forms


class UserModelForm(forms.ModelForm):
    name = forms.CharField(min_length=3, label="用户名")

    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]
        # widgets = {
        #     "name": forms.TextInput(attrs={"class": "form-control"}),
        #     "password": forms.PasswordInput(attrs={"class": "form-control"}),
        #     "age": forms.TextInput(attrs={"class": "form-control"}),
        # }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环找到所有的插件,添加了class="form-control"
        for name, field in self.fields.items():
            # if name == "password":
            #     continue
            field.widget.attrs = {"class": "form-control", "placeholder": field.label}


def user_model_form_add(request):
    """ 添加用户(ModelForm版本)"""
    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():
        # 如果数据合法,保存到数据库
        # {'name': '123', 'password': '123', 'age': 11, 'account': Decimal('0'), 'create_time': datetime.datetime(2011, 11, 11, 0, 0, tzinfo=), 'gender': 1, 'depart': }
        # print(form.cleaned_data)
        # models.UserInfo.objects.create(..)
        form.save()
        return redirect('/user/list/')

    # 校验失败(在页面上显示错误信息)
    return render(request, 'user_model_form_add.html', {"form": form})


总结

大家喜欢的话,给个,点个关注!给大家分享更多有趣好玩的Python 网页Web开发知识!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2023 mzh

Crated:2023-3-1

欢迎关注 『Django 网页Web开发』 系列,持续更新中
欢迎关注 『Django 网页Web开发』 系列,持续更新中
『01. 安装配置Django』
『02. 创建并运行一个Django项目』
『03. 初识Django』
『04. 请求和响应,网页跳转重定向,实战简易表单模拟登陆』
『05. 数据库操作,实战用户管理』
『06. 报错:You have 26 unapplied migration(s). Your project may not work properly until you apply the migra』
『07. 模板语法』
『08. 实战项目:部门和员工管理系统(01)』
『09. 实战项目:员工编辑删除功能与靓号管理(02)』
『10. 实战项目:靓号搜索功能(03)』
『11. 实战项目:分页与页码跳转功能(04)』
『12. 实战项目:分页组件的封装 面向接口编程(05)』
『13. 实战项目:添加用户时的时间选择组件(06)』
『14. 实战项目:一些面向对象的代码结构优化(07)』
『15. 实战项目:管理员增删改查,md5密码和密码重置(08)』
『16. 实战项目:BootStrap类的进一步优化(09)』
『17. 实战项目:login业务涉及cookie、session、中间件(10)』
『18. 实战项目:登录时的验证码(11)』
『19. 实战项目:初识Ajax请求(12)』
『20. 实战项目:Ajax实战之订单管理与弹出对话框(13)』
『21. 实战项目:echart数据图表(14)』
『22. 实战项目:简单的文件上传(15)』
『23. 实战项目:Excel和form和moudleForm的文件上传(16)』
【更多内容敬请期待】


你可能感兴趣的:(python,#,Django网页Web开发,django,前端,python,后端)