【Django】开发日报_3.3_Day:员工管理系统(4)

目录

0、在数据库写入测试数据

1、在后端测试获取数据表中内容

2、加载用户列表

3、原始操作方法

(1)添加用户

优化:

 (2)删除用户

 (3)编辑用户

4、新方法采用Django的Form和ModelForm组件

 4.1 原始办法的缺点:

 4.2 Form组件

 4.3ModelForm组件

 4.4 基于ModelForm组件-实现用户添加

 4.5 基于ModelForm组件-实现用户修改

编辑用户

​编辑 小提示1:

小提示2:

小提示3: 删除还是老方法。


0、在数据库写入测试数据

step 0:修改表的编码格式utf8(支持中文)创建时设置了,这步就省略。

alter table 表名 convert to character set utf8;

step 1:插入测试数据

语法:

 insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id)values("刘东","123",23,100.68,"2022-09-01",1,3);

数据表中的数据:

部门表:

mysql> select * from app01_department;
+----+-----------+
| id | title     |
+----+-----------+
|  3 | 技术部    |
|  4 | 人力部    |
+----+-----------+
2 rows in set (0.00 sec)

员工表:

mysql> desc app01_userinfo;
+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| id          | bigint(20)    | NO   | PRI | NULL    | auto_increment |
| name        | varchar(16)   | NO   |     | NULL    |                |
| password    | varchar(64)   | NO   |     | NULL    |                |
| age         | int(11)       | NO   |     | NULL    |                |
| account     | decimal(10,2) | NO   |     | NULL    |                |
| create_time | datetime(6)   | NO   |     | NULL    |                |
| gender      | smallint(6)   | NO   |     | NULL    |                |
| depart_id   | bigint(20)    | NO   | MUL | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+
8 rows in set (0.01 sec)

step 3:查看数据表

1、在后端测试获取数据表中内容

def user_list(request):
    """用户列表"""
    #获取数据库表中的所有对象
    queryset = models.UserInfo.objects.all()
    #测试获取内容
    for obj in queryset:
        print(obj.id,obj.name,obj.account,
              obj.create_time.strftime("%Y-%m-%d"),
              obj.get_gender_display(),
              obj.depart.title
              )
    return render(request,'user_list.html')

 输出:

2、加载用户列表

user_list.html

{% extends 'layout.html' %}
{% block content %}
    <div>
        <div class="container">
            <!--按钮-->
            <div style="margin-bottom: 10px">
                <a class="btn btn-success" href="#">
                    <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.account }}</td>
                            <!--模板里面无括号,所以格式化参数也不能有 <td>{ obj.create_time.strftime("%Y-%m-%d") }</td>-->
                            <td>{
   
   { obj.create_time|date:"Y-m-d" }}</td>
                            <!--模板中参数无括号,括号是自动加的<td>{ obj.get_gender_display() }</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>
    </div>
{% endblock %}

 views.py

def user_list(request):
    """用户列表"""
    #获取数据库表中的所有对象
    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.get_gender_display(),
        obj.depart.title
    )
    """
    return render(request,'user_list.html',{"queryset":queryset})

urls.py

from django.contrib import admin
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/<int:nid>/edit/', views.depart_edit),
    #---------------------------用户管理---------------------------
    #用户列表
    path('user/list/', views.user_list),

]

访问页面:

3、原始操作方法

(1)添加用户

 urls.py

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

views.py

def user_add(request):
    """用户添加"""
    #1、处理请求
    if request.method == "GET":
        return render(request,'user_add.html')
    #处理POST请求,获取表单
    name = request.POST.get("name")
    password = request.POST.get("pwd")
    age = request.POST.get("age")
    account = request.POST.get("acc")
    create_time = request.POST.get("time")
    gender = request.POST.get("gen")
    depart_id = request.POST.get("depid")
    #存到数据库
    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/")

user_add.html

{% extends 'layout.html' %}
{% 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"><!--action可以不写,因为不写的话提交的是当前地址-->
                        {% csrf_token %}
                        <div class="form-group">
                            <label> 姓名 </label>
                            <input type="text" class="form-control" placeholder="姓名" name="name"/>
                            <label> 密码 </label>
                            <input type="text" class="form-control" placeholder="密码" name="pwd"/>
                            <label> 年龄 </label>
                            <input type="text" class="form-control" placeholder="年龄" name="age"/>
                            <label> 余额 </label>
                            <input type="text" class="form-control" placeholder="余额" name="acc"/>
                            <label> 创建时间 </label>
                            <input type="text" class="form-control" placeholder="时间" name="time"/>
                            <label> 性别 </label>
                            <input type="number" class="form-control" placeholder="性别" name="gen"/>
                            <label> 部门ID </label>
                            <input type="number" class="form-control" placeholder="部门ID" name="depid"/>
                        </div>

                        <button type="submit" class="btn btn-primary"> 提交</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

测试界面:

添加用户

 完成

 数据库显示

优化:

上面的页面中性别和部门都是手动输入的,不够人性化,这里我们加上选择下拉框进行优化。

                            <label> 性别 </label>
                            <select class="form-control" name="gen">
                                {% for item in gender_choice %}
                                    <option value="{
   
   { item.0 }}">{
   
   { item.1 }}</option>
                                {% endfor %}
                            </select>
                            <label> 部门ID </label>
                            <select class="form-control" name="depid">
                                {% for item in depart_list %}
                                    <option value="{
   
   { item.id }}">{
   
   { item.title }}</option>
                                {% endfor %}
                            </select>

 数据都是从数据库获取的:

def user_add(request):
    """用户添加"""
    if request.method == "GET":
        context = {
            'gender_choice': 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("pwd")
    age = request.POST.get("age")
    account = request.POST.get("acc")
    create_time = request.POST.get("time")
    gender = request.POST.get("gen")
    depart_id = request.POST.get("depid")
    # 存到数据库
    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/")

页面:

 (2)删除用户

urls.py

#用户删除
    path('user/delete/', views.user_delete),

views.py

def user_delete(request):
    """删除用户"""
    uid = request.GET.get("uid")
    models.UserInfo.objects.filter(id=uid).delete()
    return redirect("/user/list/")

修改 user_list.html

将按钮绑定网址

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

网页测试:

 删除

 数据库

 (3)编辑用户

urls.py

    #用户修改
    path('user/<int:uid>/edit/', views.user_edit),

views.py

def user_edit(request,uid):
    #处理用户GET请求
    if request.method == "GET":
        row_object = models.UserInfo.objects.filter(id=uid).first()
        return render(request, 'user_edit.html', {"row_object": row_object})
    #处理POST请求
    name = request.POST.get("name")
    password = request.POST.get("pwd")
    age = request.POST.get("age")
    account = request.POST.get("acc")
    create_time = request.POST.get("time")
    gender = request.POST.get("gen")
    depart_id = request.POST.get("depid")
    #修改数据表
    models.UserInfo.objects.filter(id=uid).update(name=name,password=password,age=age,
                                                    account=account,create_time=create_time,
                                                    gender=gender,depart_id=depart_id)
    # 重定向用户列表
    return redirect("/user/list/")

修改user_list.html绑定按钮

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

user_edit.py

{% extends 'layout.html' %}
{% 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"><!--action可以不写,因为不写的话提交的是当前地址-->
                        {% csrf_token %}
                        <div class="form-group">
                            <label> 姓名 </label>
                            <input type="text" class="form-control" placeholder="姓名" name="name"
                                   value="{
   
   { row_object.name }}"/>
                            <label> 密码 </label>
                            <input type="text" class="form-control" placeholder="密码" name="pwd"
                                   value="{
   
   { row_object.password }}"/>
                            <label> 年龄 </label>
                            <input type="text" class="form-control" placeholder="年龄" name="age"
                                   value="{
   
   { row_object.age }}"/>
                            <label> 余额 </label>
                            <input type="text" class="form-control" placeholder="余额" name="acc"
                                   value="{
   
   { row_object.account }}"/>
                            <label> 入门时间 </label>
                            <input type="text" class="form-control" placeholder="入门时间" name="time"
                                   value="{
   
   { row_object.create_time|date:"Y-m-d" }}"/>
                            <label> 性别 </label>
                            <input type="text" class="form-control" placeholder="性别" name="gen"
                                   value="{
   
   { row_object.gender }}"/>
                            <label> 部门ID </label>
                            <input type="text" class="form-control" placeholder="部门ID" name="depid"
                                   value="{
   
   { row_object.depart_id }}"/>
                        </div>

                        <button type="submit" class="btn btn-primary"> 提交</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

测试:

修改

提交

 数据库

4、新方法采用Django的Form和ModelForm组件

4.1 原始办法的缺点:

(1)用户提交的数据没有校验,不能判断数据是否为空。

(2)如果页面信息输入错误,没有提示

 (3)页面上,每一个字段都要手写一遍,代码量太大

(4)关联数据需要手动获取并循环展示在页面。

因为以上种种问题,企业开发根本不会用这种原始方法,而是会选择使用django的组件,处理这些事件。

 4.2 Form组件

示例:

(蓝色部分已被取代了不用写了)  

 

 更简单点使用循环:

 4.3ModelForm组件

如果觉得Form的方法还是过于啰嗦,尤其是创建类的时候,和models的写法很像

 models.py

那么,为了更好的表达这种转换关系,我们使用ModelForm。

 

modelForm还可以自定义字段

更多实用功能,后续介绍。 

4.4 基于ModelForm组件-实现用户添加

创建一个新的添加页面,基于modelform

user_list.html

 <!--按钮-->
            <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/modelform/add/">
                    <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                    新建用户ModelForm
                </a>
            </div>

样式

urls.py

 #用户添加ModelForm
    path('user/modelform/add/', views.user_model_add),

views.py

#————————————————————————————————————————————————ModelForm实例————————————————————————————————————————————————
from  django import forms

class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name","password","age","account","create_time"]
def user_model_add(request):
    """添加用户(ModelForm)"""
    #类实例化
    form = UserModelForm()
    return render(request,'user_mode_add.html',{'form':form})

user_model_add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <form method="post">
        {% csrf_token %}
        <!--因为formmodel是models的一种转化引用,所以models里面定义的内容,在formmodel中也可以引用-->
        {
   
   { form.name.label}}:{
   
   { form.name }}
        <!--循环写法-->
        {% for foo in form  %}
            {
   
   { foo.label }}:{
   
   { foo }}
        {% endfor %}
    </form>
</div>
</body>
</html>

测试页面:

在列表中加入gender和create_time和depart也是可以的,但是depart作为关联数据库返回的是对象值:

想要在输出对象时显示对象里面的内容,可以在类中创建一个__str__(self)函数。

所以,根据这个原理,我们去models.py的部门类中填写一个函数

class Department(models.Model):
    """部门表"""
    #id = models.BigAutoField(verbose_name='id',primary_key=True)#手动设置自增主键
    title = models.CharField(verbose_name='部门标题',max_length=32)#verbose_name是给自己看的注释,不会影响数据库
    #输出对象时的返回值
    def __str__(self):
        return self.title

显示内容: 

 --------------------------------------------------------------------------------------------------------------------------------

完整示例:

views.py

        usermodelform类

class UserModelForm(forms.ModelForm):
    #字段重构:编写验证规则
    name = forms.CharField(min_length=3,label="姓名")
    password = forms.CharField(min_length=6,label="密码")#validators:正则表达式,密码是6-18位数字
    # 重新定义ini方法
    def __init__(self, *args, **kwargs):
        # 引用父类的ini方法
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            # print(name,field)
            # if name == "password":
            # continue
            field.widget.attrs = {"class": "form-control", "placeholder": field.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'}),
        # ……
        # }

        user_model_add函数

def user_model_add(request):
    """添加用户(ModelForm)"""
    if request.method == "GET":
        # 类实例化
        form = UserModelForm()
        return render(request, 'user_mode_add.html', {'form': form})
    #处理POST请求并校验数据
    form = UserModelForm(data=request.POST)
    if form.is_valid():#校验成功
        #数据合法,保存数据
        #{'name': '小样', 'password': '111', 'age': 11, 'account': Decimal('0'), 'create_time': datetime.datetime(2022, 10, 1, 0, 0, tzinfo=<UTC>), 'gender': 2, 'depart': <Department: 人力部>}
        #print(form.cleaned_data)
        form.save()
        return redirect("/user/list/")
    #校验失败,在页面上显示错误信息
    #print(form.errors)
    return render(request, 'user_mode_add.html', {'form': form})

 models.py

class Department(models.Model):
    """部门表"""
    #id = models.BigAutoField(verbose_name='id',primary_key=True)#手动设置自增主键
    title = models.CharField(verbose_name='部门标题',max_length=32)#verbose_name是给自己看的注释,不会影响数据库
    #输出对象时的返回值
    def __str__(self):
        return self.title

user_model_add.html

{% extends 'layout.html' %}
{% 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">
                    <!--表单-->
                    <!--action可以不写,因为不写的话提交的是当前地址-->
                    <form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->
                        {% csrf_token %}
                        {% for obj in form %}
                            <div class="form-group">
                                <label> {
   
   { obj.label }} </label>
                                {
   
   { obj }}
                                <span style="color:red"> {
   
   { obj.errors.0 }}</span><!--错误信息以列表形式存储-->
                                <!--<input type="text" class="form-control" placeholder="姓名" name="name"/>-->
                            </div>
                        {% endfor %}
                        <button type="submit" class="btn btn-primary"> 提交</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

将错误提示改成中文

setting.py

#LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'

舒服多了

 演示:

 

 4.5 基于ModelForm组件-实现用户修改

 如果操作针对数据库建议使用ModelForm,否则使用Form。

编辑用户

        流程:点击编辑,跳转到编辑页面,同时用url传递编辑行的用户id参数。

        需求;编辑页面要有默认数据,并且提交时有错误提示,并将正确信息保存在数据库。

user_list.html

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

urls.py

 #用户修改ModelForm
    path('user/<int:nid>/edit/', views.user_model_edit),

views.py:

def user_model_edit(request, nid):
    #获取当前行数据
    row_object = models.UserInfo.objects.filter(id=nid).first()
    if request.method == "GET":
        #将默认值传递给页面
        form = UserModelForm(instance=row_object)
        return render(request, 'user_model_edit.html',{"form":form})
    #处理post请求
    form = UserModelForm(data=request.POST,instance=row_object)
    # 校验
    if form.is_valid():
        form.save()
        return redirect("/user/list/")
    return render(request,'user_model_edit.html',{"form":form})

user_model_edit.html

{% extends 'layout.html' %}
{% 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">
                    <!--表单-->
                    <!--action可以不写,因为不写的话提交的是当前地址-->
                    <form method="post" novalidate><!--novalidate:表示不采用views函数里的校验,采用自己写的页面校验-->
                        {% csrf_token %}
                        {% for obj in form %}
                            <div class="form-group">
                                <label> {
   
   { obj.label }} </label>
                                {
   
   { obj }}
                                <span style="color:red"> {
   
   { obj.errors.0 }}</span><!--错误信息以列表形式存储-->
                                <!--<input type="text" class="form-control" placeholder="姓名" name="name"/>-->
                            </div>
                        {% endfor %}
                        <button type="submit" class="btn btn-primary"> 提交</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

测试页面:

 小提示1:

数据表时间字段中将DatetimeFiled修改为DateFiled可以省略时分秒,

 但是,只要变更数据库,就要执行迁移指令:

打开

输入

makemigrations
migrate

 完成。

小提示2:

使用ModelForm额外添加字段

小提示3: 删除还是老方法。

猜你喜欢

转载自blog.csdn.net/qq_51701007/article/details/126837937