Django之modelform使用

Django新增修改数据功能优化

目录

1.新增数据功能优化

2.修改数据功能优化

在我们做数据优化处理之前, 我们先回顾下传统的写法, 是如何实现增加修改的。

我们需要在templates里面新建前端的页面, 需要有新增还要删除, 比如说员工数据的新增, 那需要有很多个输入框, 那html结构里面, 都需要一一写入label, input, 选择框select里面配合option这样的组件。包括在后端写代码的时候, 在user.py那个views里面, 新增函数里面需要列出每一个字段并赋值, 就像以下代码:

name = request.POST.get("name")
age = request.POST.get("age")
gender = request.POST.get("gender")
salary = request.POST.get("salary")
dtime = request.POST.get("dtime")
depart = request.POST.get("depart")

这样的写法, 会显得非常冗余, 代码质量不高, 这篇文章, 我们就是要解决这种问题的, 优化新增和修改功能, 使代码质量变得更高, 不出现冗余代码的情况(前端和后端代码需要达成的一致要求)。
还要一点就是传统的写法, 它没有数据校验功能。

那这篇文章, 我们要讲的是modelform, 它可以很好的解决我们上面所提到的一些问题。

一、新增数据功能优化

我们打开user.py, 编辑以下代码:

class userInfoModelForm(forms.ModelForm):name = forms.CharField(min_length=2, label="姓名")class Meta:model = models.UserInfo# 在UserInfo表给里面指定的字段可使用# fields = ["name", "gender"] # 代表可以用name和gender这两个字段# 所有的UserInfo表格的字段都使用fields = "__all__"# 相当于代替了之前的以下代码:#name = request.POST.get("name")# age = request.POST.get("age")# gender = request.POST.get("gender")# salary = request.POST.get("salary")# dtime = request.POST.get("dtime")# depart = request.POST.get("depart")# 如果是想要某张表格的某个字段不想用, 那就可以用exclude# exclude = ["create_time"]# 由于我们的userInfoModelForm类继承了forms.ModelForm类, 所以我们写构造函数的时候, 需要传入*args, **kwargs这两个参数def __init__(self, *args, **kwargs):super(userInfoModelForm, self).__init__(*args, **kwargs)# item是属性名, field是属性值for item, field in self.fields.items():# 给输入框input增加一个class属性field.widget.attrs.update({"class": "form-control"})

然后我们继续写添加函数在user.py里面:

def user_add_modelform(request):if request.method == "GET":title = "添加信息2.0版本"form = userInfoModelForm()return render(request, "user/user_modelform.html", {"title": title, "form": form})# 接受表单提交过来的数据form = userInfoModelForm(request.POST)# 校验数据是否完整if form.is_valid():# 存储到数据库form.save()return redirect("/user/")# 如果数据不完整,则返回当前添加页面,展示错误信息return render(request, "user/user_modelform.html", {"form": form})

这里我们需要创建一个userInfoModelForm对象。并将它传给前端。需要注意的是form = userInfoModelForm(request.POST)这行代码, 里面需要加request.POST, 这个是为了接受表单提交过来的数据, 提交表单数据, 就是用的POST方法。所以这里必须要加request.POST。

我们在templates里面的user文件夹里, 创建user_modelform.html:

{% extends "index/model_tmp.html" %}
{% load static %}{% block css %}<link rel="stylesheet" href="{% static 'css/layui.css' %}">
{% endblock %}{% block content %}<div class="container"><h1>{{ title }}</h1><form method="post">{% csrf_token %}{% for filed in form %}
{#       filed.label这里面就是获取我们在models.py里面创建表格里面的每一个字段里面有个verbose_name这个参数的值         #}<label for="exampleInputEmail1">{{ filed.label }}</label>{{ filed }}{#       展示错误信息         #}<span style="color: red">{{ filed.errors.0 }}</span><br>{% endfor %}<button type="submit" class="btn btn-success">提交</button></form></div>
{% endblock %}{% block js %}<script src="{% static "js/layui.js" %}"></script><script>layui.use(function () {var laydate = layui.laydate;// 渲染laydate.render({// 这个id是员工入职时间的那个input输入框的id, 我们使用了modelform, 它会自动给我们每一个input都会生成一个id,// 格式为id_数据库字段名, 我们数据库员工表格里面的员工入职时间的那个字段是create_time, 所以id是id_create_time。elem: '#id_create_time'});});</script>
{% endblock %}

我们可以从代码中发现, 我们前端不用再一一的去写input, select那种输入框选择框了, filed就是input, 要展现label组件, 那就是filed.label, 如果提交表单之后有错误信息的话, 那就展示错误信息, 用filed.errors.0来展示, 还有, modelform它会帮我们每一个input输入框都会自动创建id, 就比如我们员工入职的时间那栏, id为id_create_time, 所以下面的script标签里面, 那个elem参数要写#id_create_time。

urls.py:

"""project_simple URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views1. Add an import:  from my_app import views2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views1. Add an import:  from other_app.views import Home2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf1. Import the include() function: from django.urls import include, path2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from project_one.views import depart, userurlpatterns = [# path('admin/', admin.site.urls),path("", depart.index),path("depart/", depart.depart),path("depart/add/", depart.add_depart),path("depart/<int:nid>/modify/", depart.depart_modify),path("depart/<int:nid>/del/", depart.del_depart),path("user/", user.user_info),path("user/add/", user.user_add),path("user/<int:nid>/modify/", user.user_modify),path("user/<int:nid>/del/", user.user_del),# 使用modelform来解决新增path("user/add/modelform", user.user_add_modelform)
]

完善user_list.html:

{% extends "index/model_tmp.html" %}{% block content %}<div class="container"><a href="/user/add/" class="btn btn-success">添加信息</a>{#  这个是优化过的新增功能  #}<a href="/user/add/modelform" class="btn btn-warning">添加信息</a><div class="panel panel-danger"><div class="panel-heading"><h3 class="panel-title">部门表</h3></div><div class="panel-body"><table class="table table-hover"><thead><tr><th>ID</th><th>姓名</th><th>性别</th><th>薪水</th><th>年龄</th><th>入职时间</th><th>部门</th></tr></thead><tbody>{% for data in user_list %}<tr><th scope="row">{{ data.id }}</th><td>{{ data.name }}</td><td>{{ data.get_gender_display }}</td><td>{{ data.salary }}</td><td>{{ data.age }}</td><td>{{ data.create_time|date:"Y-m-d" }}</td><td>{{ data.department.title }}</td><td style="color: green"><a href="/user/{{ data.id }}/modify/"><span style="color: green;" class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a><a href="/user/{{ data.id }}/del/"><span style="color: red;" class="glyphicon glyphicon-trash" aria-hidden="true"></span></a></td></tr>{% endfor %}</tbody></table></div></div></div>
{% endblock %}

运行结果:

点击右边黄色按钮的添加信息

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

由此可见, 我们成功的添加了数据。

二、修改数据功能优化

修改功能, 和刚才那个新增功能, 有异曲同工之妙, 但也有天壤之别。

我们同样的打开user.py:

def user_modify_modelform(request, nid):# 获取要修改的那行数据obj = models.UserInfo.objects.filter(id=nid).first()if request.method == "GET":title = "修改信息2.0版本"# 这个代码的作用是当我们进入user_modelform.html界面的时候, 所有的输入框都会出现需要修改数据中的每一个字段内容里面的文字form = userInfoModelForm(instance=obj)return render(request, "user/user_modelform.html", {"title": title, "form": form})# 接受表单提交过来的数据form = userInfoModelForm(request.POST, instance=obj)# 校验数据是否完整if form.is_valid():# 存储到数据库form.save()return redirect("/user/")# 如果数据不完整,则返回当前修改页面,展示错误信息return render(request, "user/user_modelform.html", {"form": form})

这里面多了个obj = models.UserInfo.objects.filter(id=nid).first()这行代码, 因为我们修改某一行数据的时候, 需要先获取要修改的那行的所有数据, 并且展示到每一个输入框里面, 这样我们在做修改的时候, 才知道我们需要修改哪一行数据, 避免混淆。还有, 就是在创建userInfoModelForm对象的时候, 里面要传入instance参数, instance要传入的值就是我们获取到要修改的那行数据。其他的写法, 都和上面的新增数据一样。

这里面, 我们新增数据和修改数据, 都是用的同一个html文件, 都是user_modelform.html, 我们把它作为了新增和修改的公用页面。

urls.py:

"""project_simple URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views1. Add an import:  from my_app import views2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views1. Add an import:  from other_app.views import Home2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf1. Import the include() function: from django.urls import include, path2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from project_one.views import depart, userurlpatterns = [# path('admin/', admin.site.urls),path("", depart.index),path("depart/", depart.depart),path("depart/add/", depart.add_depart),path("depart/<int:nid>/modify/", depart.depart_modify),path("depart/<int:nid>/del/", depart.del_depart),path("user/", user.user_info),path("user/add/", user.user_add),path("user/<int:nid>/modify/", user.user_modify),path("user/<int:nid>/del/", user.user_del),path("user/add/modelform", user.user_add_modelform),path("user/<int:nid>/modify/modelform", user.user_modify_modelform)
]

完善user_list.html:

{% extends "index/model_tmp.html" %}{% block content %}<div class="container"><a href="/user/add/" class="btn btn-success">添加信息</a>{#  这个是优化过的新增功能  #}<a href="/user/add/modelform" class="btn btn-warning">添加信息</a><div class="panel panel-danger"><div class="panel-heading"><h3 class="panel-title">部门表</h3></div><div class="panel-body"><table class="table table-hover"><thead><tr><th>ID</th><th>姓名</th><th>性别</th><th>薪水</th><th>年龄</th><th>入职时间</th><th>部门</th></tr></thead><tbody>{% for data in user_list %}<tr><th scope="row">{{ data.id }}</th><td>{{ data.name }}</td><td>{{ data.get_gender_display }}</td><td>{{ data.salary }}</td><td>{{ data.age }}</td><td>{{ data.create_time|date:"Y-m-d" }}</td><td>{{ data.department.title }}</td><td style="color: green">{# 我们这里使用modelform来完成修改操作 #}<a href="/user/{{ data.id }}/modify/modelform"><span style="color: green;" class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a><a href="/user/{{ data.id }}/del/"><span style="color: red;" class="glyphicon glyphicon-trash" aria-hidden="true"></span></a></td></tr>{% endfor %}</tbody></table></div></div></div>
{% endblock %}

user.py完整代码(包含之前写过的所有内容):

from django.shortcuts import render, redirect
from django import formsfrom project_one import models# Create your views here.
def user_info(request):user_list = models.UserInfo.objects.all()return render(request, "user/user_list.html", {"user_list": user_list})def user_add(request):if request.method == "GET":content = {"gender_choices": models.UserInfo.gender_choices,"depart_list": models.Department.objects.all()}return render(request, "user/user_add.html", content)name = request.POST.get("name")age = request.POST.get("age")gender = request.POST.get("gender")salary = request.POST.get("salary")dtime = request.POST.get("dtime")depart = request.POST.get("depart")models.UserInfo.objects.create(name=name, gender=gender, salary=salary, age=age, create_time=dtime,department_id=depart)return redirect("/user/")def user_modify(request, nid):if request.method == "GET":data = models.UserInfo.objects.filter(id=nid).first()content = {"gender_choices": models.UserInfo.gender_choices,"depart_list": models.Department.objects.all()}return render(request, "user/user_modify.html", {"content": content, "data": data})name = request.POST.get("name")age = request.POST.get("age")gender = request.POST.get("gender")salary = request.POST.get("salary")dtime = request.POST.get("dtime")depart = request.POST.get("depart")models.UserInfo.objects.filter(id=nid).update(name=name, gender=gender, salary=salary, age=age, create_time=dtime,department_id=depart)return redirect("/user/")def user_del(request, nid):models.UserInfo.objects.filter(id=nid).delete()return redirect("/user/")class userInfoModelForm(forms.ModelForm):name = forms.CharField(min_length=2, label="姓名")class Meta:model = models.UserInfo# 所以的UserInfo表格的字段都使用fields = "__all__"# 如果是想要某张表格的某个字段不想用, 那就可以用exclude# exclude = ["create_time"]# 由于我们的userInfoModelForm类继承了forms.ModelForm类, 所以我们写构造函数的时候, 需要传入*args, **kwargs这两个参数def __init__(self, *args, **kwargs):super(userInfoModelForm, self).__init__(*args, **kwargs)# item是属性名, field是属性值for item, field in self.fields.items():# 给输入框input增加一个class属性field.widget.attrs.update({"class": "form-control"})def user_add_modelform(request):if request.method == "GET":title = "添加信息2.0版本"form = userInfoModelForm()return render(request, "user/user_modelform.html", {"title": title, "form": form})# 接受表单提交过来的数据form = userInfoModelForm(request.POST)# 校验数据是否完整if form.is_valid():# 存储到数据库form.save()return redirect("/user/")# 如果数据不完整,则返回当前添加页面,展示错误信息return render(request, "user/user_modelform.html", {"form": form})def user_modify_modelform(request, nid):# 获取要修改数据的那行数据obj = models.UserInfo.objects.filter(id=nid).first()if request.method == "GET":title = "修改信息2.0版本"# 这个代码的作用是当我们进入user_modelform.html界面的时候, 所有的输入框都会出现需要修改数据中的每一个字段内容里面的文字form = userInfoModelForm(instance=obj)return render(request, "user/user_modelform.html", {"title": title, "form": form})# 接受表单提交过来的数据form = userInfoModelForm(request.POST, instance=obj)# 校验数据是否完整if form.is_valid():# 存储到数据库form.save()return redirect("/user/")# 如果数据不完整,则返回当前修改页面,展示错误信息return render(request, "user/user_modelform.html", {"form": form})

运行结果:

比如说, 我们修改第二行数据:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

我们发现, 数据修改成功了。

好了, 这篇文章关于优化新增和修改功能的内容, 就到此为止了。

以上就是Django新增修改数据功能优化的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5 应用程序缓存:原理、实践与演进

在 Web 技术的发展历程中&#xff0c;HTML5 引入的应用程序缓存&#xff08;Application Cache&#xff09;曾是提升 Web 应用离线体验的重要技术。它允许 Web 应用进行缓存&#xff0c;使用户在没有因特网连接时也能访问应用&#xff0c;为 Web 应用带来了显著的优势。然而&am…

【问题笔记】解决python虚拟环境运行脚本无法激活问题

【问题笔记】解决python虚拟环境运行脚本无法激活问题 错误提示问题所在解决方法**方法 1&#xff1a;临时更改执行策略****方法 2&#xff1a;永久更改执行策略** **完整流程示例** 错误提示 PS F:\PythonProject\0419graphrag-local-ollama-main> venv1\Scripts\activate…

解决echarts饼图label显示不全的问题

解决办法 添加如下配置&#xff1a; labelLayout: {hideOverlap: false},

Pandas数据合并与重塑

在数据处理与分析的领域中&#xff0c;Pandas 无疑是一颗璀璨的明星。它提供了丰富且强大的功能&#xff0c;让我们能够轻松应对各种复杂的数据操作。其中&#xff0c;数据合并与重塑是两个至关重要的环节&#xff0c;它们能够帮助我们整合不同来源的数据&#xff0c;调整数据的…

Nodejs数据库单一连接模式和连接池模式的概述及写法

概述 单一连接模式和连接池模式是数据库连接的两种主要方式&#xff1a; 单一连接模式&#xff1a; 优点&#xff1a;实现简单&#xff0c;适合小型应用缺点&#xff1a;每次请求都需要创建新连接&#xff0c;连接创建和销毁开销大&#xff0c;并发性能差&#xff0c;容易出…

将 DeepSeek 集成到 Spring Boot 项目实现通过 AI 对话方式操作后台数据

文章目录 项目简介GiteeMCP 简介环境要求项目代码核心实现代码MCP 服务端&#xff08;批量注册 Tool&#xff09;MCP 客户端&#xff08;调用 DeepSeek&#xff09; DeepSeek APIDockersse 连接ws 连接&#xff08;推荐&#xff09;http 连接 Cherry Studio配置模型配置 MCP调用…

【HDFS入门】HDFS性能调优实战:压缩与编码技术深度解析

目录 1 HDFS性能调优概述 2 HDFS压缩技术原理与应用 2.1 常见压缩算法比较 2.2 压缩流程架构 2.3 压缩配置实践 3 列式存储编码技术 3.1 ORC与Parquet对比 3.2 ORC文件结构 3.3 Parquet编码流程 4 性能调优实战建议 4.1 压缩选择策略 4.2 编码优化技巧 5 性能测试…

HCIP --- OSPF综合实验

一、拓扑图 二、实验要求 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址;R4作为企业边界路由器&#xff0c;出口公网地址需要通过PPP协议获取&#xff0c;并进行chap认证。 2&#xff0c;整个0SPF环境IP基于172.16.0.8/16划分。 3&#xff0c;所有设备均可访问R5的环…

c++:线程(std::thread)

目录 从第一性原理出发&#xff1a;为什么需要线程&#xff1f; ✅ 本质定义&#xff1a; &#x1f4cc; 使用基本语法&#xff1a; 线程之间的“并发”与“并行”的区别 线程安全与数据竞争&#xff08;Race Condition&#xff09; 如何让线程“安全地”访问数据&#x…

PCL软件架构

Point Cloud Library (PCL) 采用模块化设计,提供了丰富的点云处理功能。以下是PCL的核心架构和主要类的详细介绍。 一、PCL整体架构 PCL的架构可以分为以下几个主要层次: 数据表示层:基础点云数据结构和基本操作 算法层:各种点云处理算法实现 I/O层:点云数据的输入输出 …

CCLinkIE转EtherCAT边缘计算网关构建智能产线:跨协议设备动态组网与数据优化传输

一、行业背景 随着新能源汽车市场爆发式增长&#xff0c;汽车制造企业对产线效率、设备协同性及柔性生产能力的要求显著提升。传统产线多采用CC-LinkIEFieldBasic&#xff08;CCLINKIEFB&#xff09;协议的三菱PLC控制系统&#xff0c;而新一代伺服驱动设备普遍采用EtherCAT协…

模态双侠闯江湖:SimTier 分层破局,MAKE 智炼新知

目录 利用多模态表示提升淘宝展示广告效果&#xff1a;挑战、方法与洞察摘要1 引言2 预备知识推荐模型中的ID特征基于ID的模型结构 3 多模态表示的预训练3.1 语义感知对比学习3.2 预训练数据集的构建3.3 优化 4 与推荐模型的集成4.1 观察和见解4.2 方法一&#xff1a;SimTier4.…

基于大模型的下肢静脉曲张全流程预测与诊疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 1.3 研究方法与数据来源 二、下肢静脉曲张概述 2.1 定义与病理生理 2.2 风险因素与临床表现 2.3 诊断方法与现有治疗手段 三、大模型预测原理与构建 3.1 大模型技术简介 3.2 预测模型的数据收集与预处理 3.…

跨站脚本(XSS) 的详细分类、对比及解决方案

以下是 跨站脚本&#xff08;XSS&#xff09; 的详细分类、对比及解决方案&#xff1a; 一、XSS的分类与详解 1. 反射型XSS&#xff08;非持久型XSS&#xff09; 定义&#xff1a;攻击载荷通过URL参数传递&#xff0c;服务器直接返回到页面中&#xff0c;需用户主动触发。 工…

thinkphp实现图像验证码

示例 服务类 app\common\lib\captcha <?php namespace app\common\lib\captcha;use think\facade\Cache; use think\facade\Config; use Exception;class Captcha {private $im null; // 验证码图片实例private $color null; // 验证码字体颜色// 默认配置protected $co…

swift-12-Error处理、关联类型、assert、泛型_

一、错误类型 开发过程常见的错误 语法错误&#xff08;编译报错&#xff09; 逻辑错误 运行时错误&#xff08;可能会导致闪退&#xff0c;一般也叫做异常&#xff09; 2.1 通过结构体 第一步 struct MyError : Errort { var msg: String &#xff5d; 第二步 func divide(_ …

实验扩充 LED显示4*4键位值

代码功能概述 键盘扫描&#xff1a; 使用 KeyPort&#xff08;定义为 P1&#xff09;作为键盘输入端口。扫描 4x4 矩阵键盘&#xff0c;检测按键并返回按键编号&#xff08;0~15&#xff09;。 数码管显示&#xff1a; 根据按键编号&#xff0c;从 SegCode 数组中获取对应数码…

从零开始搭建CLIP模型实现基于文本的图像检索

目录 CLIP原理简介代码实现参考链接 CLIP原理简介 论文链接&#xff0c;源码链接 CLIP模型由OpenAI在2021年提出&#xff0c;利用双Decoder&#xff08;Dual Encoder&#xff09;的架构来学习图像和文本之间的对应关系&#xff0c;是多模态大模型的开创之作&#xff0c;为后续许…

熊海cms代码审计

目录 sql注入 1. admin/files/login.php 2. admin/files/columnlist.php 3. admin/files/editcolumn.php 4. admin/files/editlink.php 5. admin/files/editsoft.php 6. admin/files/editwz.php 7. admin/files/linklist.php 8. files/software.php 9. files…

[Java微服务组件]注册中心P3-Nacos中的设计模式1-观察者模式

在P1-简单注册中心实现和P2-Nacos解析中&#xff0c;我们分别实现了简单的注册中心并总结了Nacos的一些设计。 本篇继续看Nacos源码&#xff0c;了解一下Nacos中的设计模式。 目录 Nacos 观察者模式 Observer Pattern观察者模式总结 Nacos 观察者模式 Observer Pattern 模式定…