0
点赞
收藏
分享

微信扫一扫

Python Web开发记录 Day8:Django part2 部门管理

yongxinz 03-18 18:00 阅读 2

在上一篇博客中我们简要了解了Django,并用它实现了几个案例,接下来将进入一个用户管理系统web项目的开发,本篇内容主要围绕部门管理,后续篇章中我们会继续做用户管理、靓号管理、管理员管理、账户登录、以及Ajax等内容,接下来咱们就一起开始动手完成部门管理界面、功能的实现。

1、部门列表

首先我们先拟定一个草图,大致规划一下要实现成什么模样:
image-20240308144423959
补充一点儿,在Django项目中有几个常用的.py文件和templates目录,此处来解释一下它们几个的作用:

  • urls.py: 这个文件负责项目的URL声明,也就是网站的“目录”。它告诉Django某个特定的URL模式(通过正则表达式或路径表达式定义)被指向哪个视图(View)。当用户访问一个URL时,Django会使用urls.py文件来寻找匹配的URL模式,并将请求转发给相应的视图函数进行处理。

  • views.py: 视图文件是Django应用的核心之一,它接收用户的请求,并返回相应的响应。简单来说,视图决定了用户请求应该如何被处理和响应。在视图中,你可以执行如查询数据库、处理表单数据、生成需要返回给用户的HTML页面或其他类型的响应等操作。

  • models.py: 这个文件定义了应用中的数据模型,即你的数据库表格以及它们之间的关系(如一对多、多对多等)。Django的ORM(对象关系映射)允许你以Python类的形式定义你的数据模型,而无需直接编写SQL语句。当定义好模型后,Django可以帮助你自动地根据这些定义创建数据库表,以及执行数据查询和修改操作。

总的来说,urls.py定义了URL路径和视图之间的映射,views.py处理请求并返回响应,models.py定义了应用的数据结构。这三个组件共同工作,使得Django框架能够以一种结构化和高效的方式开发动态网站和应用。

  • templates文件夹:文件下的HTML文件扮演的是模板的角色。这些模板文件定义了网页的结构和布局,它们通常包含HTML代码,并且可以包含Django模板语言(DTL)标签过滤器,这些特殊的语法让你能够插入Python变量的值、执行循环、条件判断等动态内容的生成。

简单来说,templates下的HTML文件让你能够以一种灵活而且高效的方式设计和修改你的网页外观和内容,而无需每次都手动编写或修改大量的HTML代码。通过将逻辑(在视图中处理)和表示(在模板中定义)分离,Django的模板系统支持了网站的快速开发和维护。

然后接下来以部门列表为例,截图详细展示一下这部分实现的思路:

在这里插入图片描述
models.py

from django.db import models

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

    def __str__(self):
        return self.title

image-20240308160833164
urls.py

from django.urls import path
from api.views import depart,user,pretty

urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
]

image-20240308160851697
views.py

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

    page_object = Pagination(request, queryset, page_size=2)
    page_object.html()

    context = {
        "queryset": page_object.page_queryset,
        "page_string": page_object.page_string,
    }
    return render(request, 'depart_list.html', context)

image-20240308160913791
layout.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' %}">
    <style>
        .navbar {
            border-radius: 0;
        }
    </style>
    {% block css %}

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

        <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="/pretty/list">靓号管理</a></li>

                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></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="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">注销</a></li>
                    </ul>
                </li>

            </ul>
        </div>
    </div>
</nav>

<div>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</div>

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

{% endblock %}
</body>
</html>

depart_list.html

{% extends '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" aria-hidden="true"></span>
                新建部门
            </a>
        </div>

        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-list" aria-hidden="true"></span>
                部门列表
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <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>
            <ul class="pagination">
            {{ page_string }}
        </ul>
    </div>
{% endblock %}

效果:

image-20240308161027410

2、模板的继承

在Django中,模板继承是一种强大的特性,它允许你定义一个基础模板(通常称为"父模板"),其他模板(“子模板”)可以继承并重用这个父模板的结构和元素。这样做的好处是可以避免重复的代码,让你的模板更加组织化,易于管理和维护。

1.父模板

父模板定义了网站的基本布局和共享元素,如头部、导航栏、页脚等。它还可以定义一些可被子模板覆盖的块(block)。在Django模板语言中,你可以使用{% block block_name %}{% endblock %}语法来定义这些块。

2.子模板

子模板继承自父模板,并且可以重写父模板中的一个或多个块内容。要在子模板中继承父模板,需要在文件顶部使用{% extends "base.html" %}(假设父模板命名为base.html)声明。之后,子模板就可以通过{% block %}标签重写父模板中定义的块。

3.继承的工作原理

当请求一个使用了模板继承的视图时,Django首先加载子模板,并确定它继承自哪个父模板。然后,Django处理父模板中的所有内容,但是对于每个在子模板中被重写的块,Django会用子模板中的定义替换父模板中的原始内容。

这样,你就可以在父模板中定义整个网站或应用的通用布局,而在子模板中只关注每个页面的特定内容。这种方法极大地减少了重复代码,提高了开发效率和网站的一致性。

举个例子,如果你有一个网站,所有页面的头部和脚部布局都是相同的,你就可以把这些共通部分放在父模板中,然后为网站的每个页面创建一个子模板,只定义该页面特有的内容部分。这样,无论何时需要修改通用布局,你只需在父模板中修改一次即可自动更新所有页面,极大地简化了维护工作。

了解了模板的继承,将对我们后续项目开发省很多功夫,我们可以先定义一个布局文件layout.html,方便我们后续来使用(前面部门列表也用到了它)。

定义模板:layout.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' %}">
    <style>
        .navbar {
            border-radius: 0;
        }
    </style>
    {% block css %}

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

        <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="/pretty/list">靓号管理</a></li>

                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></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="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">注销</a></li>
                    </ul>
                </li>

            </ul>
        </div>
    </div>
</nav>

<div>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</div>

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

{% endblock %}
</body>
</html>

模版继承:

{% extends 'layout.html' %}

{% block css%}
    <link rel="stylesheet" href="{% static 'plugins...min.css' %}">
    <style>
    ...
    </style>
{% endblock%}

{% block content %}
    <h1>首页</h1>
{% endblock %}

{% block js  %}
    <script src="{% static 'js/jquery.min.js' %}"></script>
{% endblock %}
3、添加部门

同样地思路,我们接着来完成添加部门:

urls.py

from django.urls import path
from api.views import depart,user,pretty

urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
]

views.py

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/")

depart_add.html

{% extends 'layout.html' %}
{% block content %}
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title" style="font-weight: bold">新建部门</h3>
        </div>
        <div class="panel-body">
            <form method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="title">标题</label>
                    <input type="text" class="form-control" id="title" placeholder="标题" name="title"/>
                </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>
{% endblock %}
{% endblock %}

效果:

在这里插入图片描述

4、编辑部门

然后,来完成编辑部门,随着思路一遍遍地路过,会越来越清晰。

urls.py

from django.urls import path
from api.views import depart,user,pretty

urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/<int:nid>/edit/", depart.depart_edit),
]

可能朋友会注意到edit这里多了个<int:nid>,其实它是一个路径转换器,用于从URL中捕获并传递一个整数参数给对应的视图函数。例如:当有一个请求的URL符合depart/<数字>/edit/的模式时,例如depart/123/edit/,Django会解析这个URL,提取出数字123,并以nid=123的形式将其传递给depart.depart_edit视图函数。

views.py

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)
    # 重定向回部门列表
    return redirect("/depart/list/")

depart_edit.html

{% extends 'layout.html' %}

{% block content %}

    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title" style="font-weight: bold">修改部门</h3>
            </div>
            <div class="panel-body">
                <form method="post">
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="title">标题</label>
                        <input type="text" class="form-control" id="title" placeholder="标题" name="title"
                               value="{{ row_object.title }}"/>
                    </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>

{% endblock %}

效果:

在这里插入图片描述

5、删除部门

最后,来完成删除部门,到这里有了前几个功能的熟悉,已经轻松许多了。

urls.py

from django.urls import path
from api.views import depart,user,pretty

urlpatterns = [
    # 部门管理
    path("depart/list/", depart.depart_list),
    path("depart/add/", depart.depart_add),
    path("depart/<int:nid>/edit/", depart.depart_edit),
    path("depart/delete/", depart.depart_delete),
]

views.py

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")

depart_list.html

{% extends '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" aria-hidden="true"></span>
                新建部门
            </a>
        </div>

        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-list" aria-hidden="true"></span>
                部门列表
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <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>
            <ul class="pagination">
            {{ page_string }}
        </ul>
    </div>
{% endblock %}

效果:

在这里插入图片描述

6、整体效果

在这里插入图片描述

关于部门管理的实现就到这里,后续会继续实现用户管理、靓号管理、管理员管理、账户登录、以及Ajax等内容。

举报

相关推荐

0 条评论