Django教程第2章| Web开发实战-用户管理

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 基于Django实现用户管理:增删改查,搜索,分页。【2月更文挑战第22天】

前言

从第2章开始,我们正式以实战为核心开发用户管理系统,计划实现效果图所有模块功能。

本章我们将开始实现我们第一个功能模块:用户管理。

技术栈

Boostrap、jQuery、Django

功能模块

模块 进度 功能点
部门管理 完成 增删改查,搜索,分页
用户管理 完成 增删改查,搜索,分页
认证 完成 登录/验证码/修改密码
数据统计 完成 echarts折线图,柱状图,饼图
文件上传 完成 解析文件到db,form表单上传图片

效果图

image.gif 编辑

image.gif 编辑

image.gif 编辑

用户管理案例

基于mysite项目创建名为 ums 的app

1.创建应用程序

python manage.py startapp ums

image.gif

模板文件和静态文件分别放入templates和static文件夹,django会自动加载到容器。

如果你像放到其他位置可以在 settings.py 里面搜索template和static进行更改路径(非特殊需求不建议更改)。

image.gif 编辑

2.数据库配置

mysite/settings.py文件中配置你的MySQL连接信息

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

image.gif

3.下载mysqlclient

mysqlclient是django 数据库连接库,负责数据的操作和持久化,初始化表结构。

pip install mysqlclient

image.gif

4.定义模型

ums/models.py 放入以下内容

class UserInfo(models.Model):
    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    age = models.IntegerField(verbose_name='年龄')
    salary = models.DecimalField(verbose_name='工资', max_digits=10, decimal_places=2)
    gender_choices =(
        (1, '男'),
        (2, '女')
    )
    gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
    create_time = models.DateTimeField(verbose_name='创建时间')

image.gif

初始化表结构

$ python manage.py makemigrations
$ python manage.py migrate

image.gif

5、编写视图

ums/views.py 编写用户增删改查

def user_list(request):
    """ 查询用户列表 """
    # 获取所有用户列表 [obj,obj,obj]
    queryset = models.UserInfo.objects.all()
    return render(request, 'user_list.html', {'queryset': queryset})
def user_add(request):
    """ 添加用户 """
    if request.method == "GET":
        context = {
            'gender_choices': models.UserInfo.gender_choices,
            "dept_list": models.Department.objects.all()
        }
        return render(request, 'user_add.html', context)
    # 获取用户提交的数据
    user = request.POST.get('username')
    pwd = request.POST.get('pwd')
    age = request.POST.get('age')
    salary = request.POST.get('salary')
    ctime = request.POST.get('ctime')
    gender = request.POST.get('gd')
    dept = request.POST.get('dp')
    # 添加到数据库中
    models.UserInfo.objects.create(username=user, password=pwd, age=age,
                                   salary=salary, create_time=ctime,
                                   gender=gender, dept_id=dept)
    # 返回到用户列表页面
    return redirect("/user/list/")
def user_delete(request, nid):
    """ 删除用户 """
    models.UserInfo.objects.filter(id=nid).delete()
    return redirect('/user/list/')
def user_edit(request, nid):
    """ 编辑用户 """
    row_object = models.UserInfo.objects.filter(id=nid).first()
    if request.method == "GET":
        # 根据ID去数据库获取要编辑的那一行数据(对象)
        form = UserModelForm(instance=row_object)
        return render(request, 'user_edit.html', {'form': form})
    form = UserModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        # 默认保存的是用户输入的所有数据,如果想要再用户输入以外增加一点值
        # form.instance.字段名 = 值
        form.save()
        return redirect('/user/list/')
    return render(request, 'user_edit.html', {"form": form})
from django import forms
class UserModelForm(forms.ModelForm):
    username = forms.CharField(min_length=3, label="用户名")
    class Meta:
        model = models.UserInfo
        fields = ["username", "password", "age", 'salary', 'create_time', "gender", "dept"]
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环找到所有的插件,添加了class="form-control"
        for name, field in self.fields.items():
            field.widget.attrs = {"class": "form-control", "placeholder": field.label}

image.gif

6、编写模板

templates下编写模板

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>
        </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 queryset %}
                    <tr>
                        <th>{{ obj.id }}</th>
                        <td>{{ obj.name }}</td>
                        <td>{{ obj.password }}</td>
                        <td>{{ obj.age }}</td>
                        <td>{{ obj.salary}}</td>
                        <td>{{ obj.create_time|date:"Y-m-d" }}</td>
                        <td>{{ obj.get_gender_display }}</td>
                        <td>{{ obj.dept.name}}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/user/{{ obj.id }}/delete/">删除</a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{% endblock %}

image.gif

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="username" />
                    </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="salary"/>
                    </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 dept_list %}
                                <option value="{{ item.id }}">{{ item.name}}</option>
                            {% endfor %}
                        </select>
                    </div>
                    <button type="submit" class="btn btn-primary">提 交</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

image.gif

user_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" 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 %}

image.gif

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>
</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="/user/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">Johnny<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>
<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>

image.gif

7、配置路由

mysite/urls.py 配置路由

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    # 用户管理
    path('user/list/', views.user_list),
    path('user/add/', views.user_add),
    path('user/<int:nid>/edit/', views.user_edit),
    path('user/<int:nid>/delete/', views.user_delete),
]

image.gif

启动程序

python manage.py runserver

image.gif

启动后,访问127.0.0.1:8000/user/list

需要完整源代码评论区留言:想要源码

如果本文对你有帮助,记得点赞+关注,你的支持是我最大的动力!

下一章:Django教程第3章| Web开发实战 | 用户登录


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4天前
|
JSON Rust 安全
30天拿下Rust之实战Web Server
30天拿下Rust之实战Web Server
22 7
|
5天前
|
JavaScript 前端开发 数据安全/隐私保护
组件库实战 | 教你如何设计Web世界中的表单验证
该文章通过实战演练,教授了如何在Web应用中设计和实现表单验证,包括使用Vue.js处理表单输入的验证逻辑、展示错误信息以及通过插槽和组件间通信来增强表单的功能性和用户体验。
组件库实战 | 教你如何设计Web世界中的表单验证
|
9天前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
31 3
|
8天前
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
在Python Web开发中,路由和中间件是构建高效、可扩展应用的核心组件。路由通过装饰器如`@app.route()`将HTTP请求映射到处理函数;中间件则在请求处理流程中插入自定义逻辑,如日志记录和验证。合理设计路由和中间件能显著提升应用性能和可维护性。本文以Flask为例,详细介绍如何优化路由、避免冲突、使用蓝图管理大型应用,并通过中间件实现缓存、请求验证及异常处理等功能,帮助你构建快速且健壮的Web应用。
11 1
|
10天前
|
SQL 安全 Go
SQL注入不可怕,XSS也不难防!Python Web安全进阶教程,让你安心做开发!
在Web开发中,安全至关重要,尤其要警惕SQL注入和XSS攻击。SQL注入通过在数据库查询中插入恶意代码来窃取或篡改数据,而XSS攻击则通过注入恶意脚本来窃取用户敏感信息。本文将带你深入了解这两种威胁,并提供Python实战技巧,包括使用参数化查询和ORM框架防御SQL注入,以及利用模板引擎自动转义和内容安全策略(CSP)防范XSS攻击。通过掌握这些方法,你将能够更加自信地应对Web安全挑战,确保应用程序的安全性。
39 3
|
29天前
|
Java API Apache
从零到英雄的蜕变:如何用Apache Wicket打造你的第一个Web应用——不仅是教程,更是编程之旅的启航
【9月更文挑战第4天】学习Apache Wicket这一开源Java Web应用框架是一段激动人心的旅程。本文将指导你通过Maven搭建环境,并创建首个“Hello, World!”应用。从配置`pom.xml`到实现`HelloWorldApplication`类,再到`web.xml`的设置,一步步教你构建与部署简单网页。适合初学者快速上手,体验其简洁API与强大组件化设计的魅力。
23 1
|
2月前
|
数据库 开发者 Java
颠覆传统开发:Hibernate与Spring Boot的集成,让你的开发效率飞跃式提升!
【8月更文挑战第31天】在 Java 开发中,Spring Boot 和 Hibernate 已成为许多开发者的首选技术栈。Spring Boot 简化了配置和部署过程,而 Hibernate 则是一个强大的 ORM 框架,用于管理数据库交互。将两者结合使用,可以极大提升开发效率并构建高性能的现代 Java 应用。本文将通过代码示例展示如何在 Spring Boot 项目中集成 Hibernate,并实现基本的数据库操作,包括添加依赖、配置数据源、创建实体类和仓库接口,以及在服务层和控制器中处理 HTTP 请求。这种组合不仅简化了配置,还提供了一套强大的工具来快速开发现代 Java 应用程序。
59 0
|
2月前
|
Java 缓存 数据库连接
揭秘!Struts 2性能翻倍的秘诀:不可思议的优化技巧大公开
【8月更文挑战第31天】《Struts 2性能优化技巧》介绍了提升Struts 2 Web应用响应速度的关键策略,包括减少配置开销、优化Action处理、合理使用拦截器、精简标签库使用、改进数据访问方式、利用缓存机制以及浏览器与网络层面的优化。通过实施这些技巧,如懒加载配置、异步请求处理、高效数据库连接管理和启用GZIP压缩等,可显著提高应用性能,为用户提供更快的体验。性能优化需根据实际场景持续调整。
49 0
|
2月前
|
Java 数据库连接 Spring
Struts 2 插件开发竟如魔法盛宴,为框架注入超能力,开启奇幻编程之旅!
【8月更文挑战第31天】在Web开发中,Struts 2插件开发允许我们在不改动框架核心代码的前提下,通过创建实现特定接口的Java类来扩展框架功能、调整其行为或促进与其他框架(如Spring、Hibernate)的集成,从而更好地满足特定业务需求。遵循良好的设计原则与实践,能够确保插件的高效稳定运行并提升整体项目的可维护性。具体步骤包括创建项目、定义插件类、实现初始化与销毁逻辑,并将插件部署至应用中。
45 0
|
2月前
|
开发者 前端开发 开发框架
JSF与移动应用,开启全新交互体验!让你的Web应用轻松征服移动设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,移动设备的普及使得构建移动友好的应用变得至关重要。尽管JSF(JavaServer Faces)主要用于Web应用开发,但结合Bootstrap等前端框架,也能实现优秀的移动交互体验。本文探讨如何在JSF应用中实现移动友好性,并通过示例代码展示具体实现方法。使用Bootstrap的响应式布局和组件可以确保JSF页面在移动设备上自适应,并提供友好的表单输入和提交体验。尽管JSF存在组件库较小和学习成本较高等局限性,但合理利用其特性仍能显著提升用户体验。通过不断学习和实践,开发者可以更好地掌握JSF应用的移动友好性,为Web应用开发贡献力量。
38 0
下一篇
无影云桌面