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.pswp.cn/bicheng/77569.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77569.shtml
英文地址,請注明出處:http://en.pswp.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 模式定…