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新增修改數據功能優化的所有內容了, 如果有哪里不懂的地方,可以把問題打在評論區, 歡迎大家在評論區交流!!!
如果我有寫錯的地方, 望大家指正, 也可以聯系我, 讓我們一起努力, 繼續不斷的進步.
學習是個漫長的過程, 需要我們不斷的去學習并掌握消化知識點, 有不懂或概念模糊不理解的情況下,一定要趕緊的解決問題, 否則問題只會越來越多, 漏洞也就越老越大.
人生路漫漫, 白鷺常相伴!!!