• 【Django】开发日报_3.3_Day:用户表的操作


    目录

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

    数据表中的数据:

    部门表:

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

    员工表:

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

    step 3:查看数据表

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

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

     输出:

    2、加载用户列表

    user_list.html

    1. {% extends 'layout.html' %}
    2. {% block content %}
    3. <div>
    4. <div class="container">
    5. <div style="margin-bottom: 10px">
    6. <a class="btn btn-success" href="#">
    7. <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
    8. 新建用户
    9. a>
    10. div>
    11. <div class="panel panel-default">
    12. <div class="panel-heading">
    13. <span class="glyphicon glyphicon-th-list" aria-hidden="true">span>
    14. 用户列表
    15. div>
    16. <table class="table table-bordered">
    17. <thead>
    18. <tr>
    19. <th>IDth>
    20. <th>姓名th>
    21. <th>密码th>
    22. <th>年龄th>
    23. <th>账户余额th>
    24. <th>入职时间th>
    25. <th>性别th>
    26. <th>所属部门th>
    27. <th>操作th>
    28. tr>
    29. thead>
    30. <tbody>
    31. {% for obj in queryset %}
    32. <tr>
    33. <th>{{ obj.id }}th>
    34. <td>{{ obj.name }}td>
    35. <td>{{ obj.password }}td>
    36. <td>{{ obj.age }}td>
    37. <td>{{ obj.account }}td>
    38. <td>{{ obj.create_time|date:"Y-m-d" }}td>
    39. <td>{{ obj.get_gender_display }}td>
    40. <td>{{ obj.depart.title }}td>
    41. <td>
    42. <a class="btn btn-primary btn-xs" href="#">编辑a>
    43. <a class="btn btn-danger btn-xs" href="#">删除a>
    44. td>
    45. tr>
    46. {% endfor %}
    47. tbody>
    48. table>
    49. div>
    50. div>
    51. div>
    52. {% endblock %}

     views.py

    1. def user_list(request):
    2. """用户列表"""
    3. #获取数据库表中的所有对象
    4. queryset = models.UserInfo.objects.all()
    5. """
    6. #测试获取内容--python语法
    7. for obj in queryset:
    8. print
    9. (
    10. obj.id,obj.name,obj.account,
    11. obj.create_time.strftime("%Y-%m-%d"),
    12. obj.get_gender_display(),
    13. obj.depart.title
    14. )
    15. """
    16. return render(request,'user_list.html',{"queryset":queryset})

    urls.py

    1. from django.contrib import admin
    2. from django.urls import path
    3. from app01 import views
    4. urlpatterns = [
    5. #---------------------------部门管理---------------------------
    6. #部门列表
    7. path('depart/list/', views.depart_list),
    8. #部门添加
    9. path('depart/add/', views.depart_add),
    10. #部门删除
    11. path('depart/delete/', views.depart_delete),
    12. #部门修改
    13. path('depart//edit/', views.depart_edit),
    14. #---------------------------用户管理---------------------------
    15. #用户列表
    16. path('user/list/', views.user_list),
    17. ]

    访问页面:

    3、原始操作方法

    (1)添加用户

     urls.py

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

    views.py

    1. def user_add(request):
    2. """用户添加"""
    3. #1、处理请求
    4. if request.method == "GET":
    5. return render(request,'user_add.html')
    6. #处理POST请求,获取表单
    7. name = request.POST.get("name")
    8. password = request.POST.get("pwd")
    9. age = request.POST.get("age")
    10. account = request.POST.get("acc")
    11. create_time = request.POST.get("time")
    12. gender = request.POST.get("gen")
    13. depart_id = request.POST.get("depid")
    14. #存到数据库
    15. models.UserInfo.objects.create(name=name,password=password,age=age,
    16. account=account,create_time=create_time,
    17. gender=gender,depart_id=depart_id)
    18. #重定向回到部门列表
    19. return redirect("/user/list/")

    user_add.html

    1. {% extends 'layout.html' %}
    2. {% block content %}
    3. <div>
    4. <div class="container">
    5. <div class="panel panel-default">
    6. <div class="panel-heading">
    7. <h3 class="panel-title"> 新建用户 h3>
    8. div>
    9. <div class="panel-body">
    10. <form method="post">
    11. {% csrf_token %}
    12. <div class="form-group">
    13. <label> 姓名 label>
    14. <input type="text" class="form-control" placeholder="姓名" name="name"/>
    15. <label> 密码 label>
    16. <input type="text" class="form-control" placeholder="密码" name="pwd"/>
    17. <label> 年龄 label>
    18. <input type="text" class="form-control" placeholder="年龄" name="age"/>
    19. <label> 余额 label>
    20. <input type="text" class="form-control" placeholder="余额" name="acc"/>
    21. <label> 创建时间 label>
    22. <input type="text" class="form-control" placeholder="时间" name="time"/>
    23. <label> 性别 label>
    24. <input type="number" class="form-control" placeholder="性别" name="gen"/>
    25. <label> 部门ID label>
    26. <input type="number" class="form-control" placeholder="部门ID" name="depid"/>
    27. div>
    28. <button type="submit" class="btn btn-primary"> 提交button>
    29. form>
    30. div>
    31. div>
    32. div>
    33. div>
    34. {% endblock %}

    测试界面:

    添加用户

     完成

     数据库显示

    优化:

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

    1. <label> 性别 label>
    2. <select class="form-control" name="gen">
    3. {% for item in gender_choice %}
    4. <option value="{{ item.0 }}">{{ item.1 }}option>
    5. {% endfor %}
    6. select>
    7. <label> 部门ID label>
    8. <select class="form-control" name="depid">
    9. {% for item in depart_list %}
    10. <option value="{{ item.id }}">{{ item.title }}option>
    11. {% endfor %}
    12. select>

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

    1. def user_add(request):
    2. """用户添加"""
    3. if request.method == "GET":
    4. context = {
    5. 'gender_choice': models.UserInfo.gender_choices,
    6. 'depart_list': models.Department.objects.all(),
    7. }
    8. return render(request, 'user_add.html', context)
    9. #获取用户提交的请求
    10. name = request.POST.get("name")
    11. password = request.POST.get("pwd")
    12. age = request.POST.get("age")
    13. account = request.POST.get("acc")
    14. create_time = request.POST.get("time")
    15. gender = request.POST.get("gen")
    16. depart_id = request.POST.get("depid")
    17. # 存到数据库
    18. models.UserInfo.objects.create(name=name, password=password, age=age,
    19. account=account, create_time=create_time,
    20. gender=gender, depart_id=depart_id)
    21. # 重定向回到部门列表
    22. return redirect("/user/list/")

    页面:

     (2)删除用户

    urls.py

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

    views.py

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

    修改 user_list.html

    将按钮绑定网址

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

    网页测试:

     删除

     数据库

     (3)编辑用户

    urls.py

    1. #用户修改
    2. path('user//edit/', views.user_edit),

    views.py

    1. def user_edit(request,uid):
    2. #处理用户GET请求
    3. if request.method == "GET":
    4. row_object = models.UserInfo.objects.filter(id=uid).first()
    5. return render(request, 'user_edit.html', {"row_object": row_object})
    6. #处理POST请求
    7. name = request.POST.get("name")
    8. password = request.POST.get("pwd")
    9. age = request.POST.get("age")
    10. account = request.POST.get("acc")
    11. create_time = request.POST.get("time")
    12. gender = request.POST.get("gen")
    13. depart_id = request.POST.get("depid")
    14. #修改数据表
    15. models.UserInfo.objects.filter(id=uid).update(name=name,password=password,age=age,
    16. account=account,create_time=create_time,
    17. gender=gender,depart_id=depart_id)
    18. # 重定向用户列表
    19. return redirect("/user/list/")

    修改user_list.html绑定按钮

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

    user_edit.py

    1. {% extends 'layout.html' %}
    2. {% block content %}
    3. <div>
    4. <div class="container">
    5. <div class="panel panel-default">
    6. <div class="panel-heading">
    7. <h3 class="panel-title"> 修改用户 h3>
    8. div>
    9. <div class="panel-body">
    10. <form method="post">
    11. {% csrf_token %}
    12. <div class="form-group">
    13. <label> 姓名 label>
    14. <input type="text" class="form-control" placeholder="姓名" name="name"
    15. value="{{ row_object.name }}"/>
    16. <label> 密码 label>
    17. <input type="text" class="form-control" placeholder="密码" name="pwd"
    18. value="{{ row_object.password }}"/>
    19. <label> 年龄 label>
    20. <input type="text" class="form-control" placeholder="年龄" name="age"
    21. value="{{ row_object.age }}"/>
    22. <label> 余额 label>
    23. <input type="text" class="form-control" placeholder="余额" name="acc"
    24. value="{{ row_object.account }}"/>
    25. <label> 入门时间 label>
    26. <input type="text" class="form-control" placeholder="入门时间" name="time"
    27. value="{{ row_object.create_time|date:"Y-m-d" }}"/>
    28. <label> 性别 label>
    29. <input type="text" class="form-control" placeholder="性别" name="gen"
    30. value="{{ row_object.gender }}"/>
    31. <label> 部门ID label>
    32. <input type="text" class="form-control" placeholder="部门ID" name="depid"
    33. value="{{ row_object.depart_id }}"/>
    34. div>
    35. <button type="submit" class="btn btn-primary"> 提交button>
    36. form>
    37. div>
    38. div>
    39. div>
    40. div>
    41. {% 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

    1. <div style="margin-bottom: 10px">
    2. <a class="btn btn-success" href="/user/add/">
    3. <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
    4. 新建用户
    5. a>
    6. <a class="btn btn-success" href="/user/modelform/add/">
    7. <span class="glyphicon glyphicon-plus-sign" aria-hidden="true">span>
    8. 新建用户ModelForm
    9. a>
    10. div>

    样式

    urls.py

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

    views.py

    1. #————————————————————————————————————————————————ModelForm实例————————————————————————————————————————————————
    2. from django import forms
    3. class UserModelForm(forms.ModelForm):
    4. class Meta:
    5. model = models.UserInfo
    6. fields = ["name","password","age","account","create_time"]
    7. def user_model_add(request):
    8. """添加用户(ModelForm)"""
    9. #类实例化
    10. form = UserModelForm()
    11. return render(request,'user_mode_add.html',{'form':form})

    user_model_add.html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Titletitle>
    6. head>
    7. <body>
    8. <div>
    9. <form method="post">
    10. {% csrf_token %}
    11. {{ form.name.label}}:{{ form.name }}
    12. {% for foo in form %}
    13. {{ foo.label }}:{{ foo }}
    14. {% endfor %}
    15. form>
    16. div>
    17. body>
    18. html>

    测试页面:

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

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

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

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

    显示内容: 

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

    完整示例:

    views.py

            usermodelform类

    1. class UserModelForm(forms.ModelForm):
    2. #字段重构:编写验证规则
    3. name = forms.CharField(min_length=3,label="姓名")
    4. password = forms.CharField(min_length=6,label="密码")#validators:正则表达式,密码是6-18位数字
    5. # 重新定义ini方法
    6. def __init__(self, *args, **kwargs):
    7. # 引用父类的ini方法
    8. super().__init__(*args, **kwargs)
    9. for name, field in self.fields.items():
    10. # print(name,field)
    11. # if name == "password":
    12. # continue
    13. field.widget.attrs = {"class": "form-control", "placeholder": field.label}
    14. class Meta:
    15. model = models.UserInfo
    16. fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]
    17. # 样式标签
    18. # widgets = {
    19. # 输入框标签
    20. # "name":forms.TextInput(attrs={'class':'form-control'}),
    21. # "password":forms.PasswordInput(attrs={'class':'form-control'}),
    22. # ……
    23. # }

            user_model_add函数

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

     models.py

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

    user_model_add.html

    1. {% extends 'layout.html' %}
    2. {% block content %}
    3. <div>
    4. <div class="container">
    5. <div class="panel panel-default">
    6. <div class="panel-heading">
    7. <h3 class="panel-title"> 新建用户 h3>
    8. div>
    9. <div class="panel-body">
    10. <form method="post" novalidate>
    11. {% csrf_token %}
    12. {% for obj in form %}
    13. <div class="form-group">
    14. <label> {{ obj.label }} label>
    15. {{ obj }}
    16. <span style="color:red"> {{ obj.errors.0 }}span>
    17. div>
    18. {% endfor %}
    19. <button type="submit" class="btn btn-primary"> 提交button>
    20. form>
    21. div>
    22. div>
    23. div>
    24. div>
    25. {% endblock %}

    将错误提示改成中文

    setting.py

    1. #LANGUAGE_CODE = 'en-us'
    2. 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

    1. #用户修改ModelForm
    2. path('user//edit/', views.user_model_edit),

    views.py:

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

    user_model_edit.html

    1. {% extends 'layout.html' %}
    2. {% block content %}
    3. <div>
    4. <div class="container">
    5. <div class="panel panel-default">
    6. <div class="panel-heading">
    7. <h3 class="panel-title"> 编辑用户 h3>
    8. div>
    9. <div class="panel-body">
    10. <form method="post" novalidate>
    11. {% csrf_token %}
    12. {% for obj in form %}
    13. <div class="form-group">
    14. <label> {{ obj.label }} label>
    15. {{ obj }}
    16. <span style="color:red"> {{ obj.errors.0 }}span>
    17. div>
    18. {% endfor %}
    19. <button type="submit" class="btn btn-primary"> 提交button>
    20. form>
    21. div>
    22. div>
    23. div>
    24. div>
    25. {% endblock %}

    测试页面:

     小提示1:

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

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

    打开

    输入

    1. makemigrations
    2. migrate

     完成。

    小提示2:

    使用ModelForm额外添加字段

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

  • 相关阅读:
    极狐(GitLab) 马景贺:DevSecOps落地实践的挑战与应对之道
    玩转YAML配置文件占位符 ,同事纷纷直呼大佬
    计算机网络 八股
    Linux运维常用小总结
    【Java】面向对象思想
    C语言学生成绩管理系统(二叉排序树)
    2022年广西壮族自治区中职网络安全技能竞赛“Linux操作系统渗透测试详解”
    操作系统基础教程——第五章课后作业答案
    一周技术学习笔记(第78期)-顺序结构、循环结构、分支转移几十年未变也不会变...
    【快速掌握Docker】Docker高级运用汇总--Dockerfile、Docker Compose与Docker Swarm使用
  • 原文地址:https://blog.csdn.net/qq_51701007/article/details/126837937