Django 简明教程
Django – Update Data
Django ORM 使用活动记录模式进行模型类及其映射的数据库表之间的交互。模型类的实例对应于表中的一行。对象的任何属性都会导致更新相应行。
在本章中,我们将重点介绍 Django 中可用的不同方式,以更新关系数据库中已存在的行。
我们将使用下面给出的 Dreamreal model 作为本次练习:
class Dreamreal(models.Model):
website = models.CharField(max_length=50)
mail = models.CharField(max_length=50)
name = models.CharField(max_length=50)
phonenumber = models.IntegerField()
def __str__(self):
return "Website: {} Email: {} Name: {} Ph.: {}".format(self.website, self.mail, self.name, self.phonenumber)
假设您已经执行了迁移,并在模型中添加了一些对象。
Update Object From Shell
Django 具有一个有用的功能,可以使用此功能在 Django 项目的环境中调用 Python shell。使用命令 manage.py 与脚本一起使用 shell 命令 -
python manage.py shell
在 Python 提示符前,导入 Dreamreal 模型 -
>>> from myapp.models import Dreamreal
model.objects 属性返回模型管理器,其 all() 方法返回 QuerySet。我们可以通过应用过滤器来限制集合中的对象。
要返回主键为 2 的对象,请使用以下语句 -
obj = Dreamreal.objects.filter(pk = 2)
模型类具有 get() 实例方法,我们可使用此方法更改一个或多个属性的值。
obj.update(f1=v1, f2=v2, . . .)
让我们将“pk = 2”对象的名称更新为 -
obj.update(name='example')
模型管理器还具有 get() method ,该管理器获取对应于给定关键字参数的单个实例 -
obj = Dreamreal.objects.get(phonenumber = 2376970)
我们可以使用一个简单的赋值来更新一个属性。让我们更改电话号码 -
obj.phonenumber = 24642367570
要使更改持久化,您需要调用 save() method -
obj.save()
Perform Update Operation by Calling a View Function
现在让我们通过调用视图函数执行更新操作。在 views.py 文件中定义 update() 函数。此函数从其映射的 URL 接收主键作为参数。
from django.shortcuts import render
from django.http import HttpResponse
from myapp.models import Dreamreal
def update(request, pk):
obj = Dreamreal.objects.get(pk=pk)
obj.name="admin"
obj.save()
return HttpResponse("Update successful")
我们还需要通过添加新路径在 urls.py 文件中注册此视图 -
from django.urls import path
from . import views
from .views import DRCreateView, update
urlpatterns = [
path("", views.index, name="index"),
path("addnew/", views.addnew, name='addnew'),
path("update/<int:pk>", views.update, name='update'),
]
运行 Django 服务器并访问 URL http://localhost:8000/myapp/update/2 。浏览器会发出更新成功消息。
我们不希望像上述示例中那样使用硬编码值,而是期待用户输入数据。我们需要使用对应于主键的对象数据填充 HTML 表单。
Modify the update() View Function
修改 update() 视图函数,如下所示:
from django.shortcuts import render
from django.http import HttpResponse
from myapp.models import Dreamreal
def update(request, pk):
obj = Dreamreal.objects.get(pk=pk)
if request.method == "POST":
ws = request.POST['website']
mail = request.POST['mail']
nm = request.POST['name']
ph = request.POST['phonenumber']
obj.name = nm
obj.phonenumber = ph
obj.save()
return HttpResponse("<h2>Record updated Successfully</h2>")
obj = Dreamreal.objects.get(pk=pk)
context = {"obj":obj}
return render(request, "myform.html", context)
我们需要使用模板变量,用对象属性的值填充表单元素。
修改 myform.html 脚本,如下所示:
<html>
<body>
<form action="../update/{{ obj.pk }}" method="post">
{% csrf_token %}
<p><label for="website">WebSite: </label>
<input id="website" type="text" value = {{ obj.website }} name="website" readonly></p>
<p><label for="mail">Email: </label>
<input id="mail" type="text" value = {{ obj.mail }} name="mail" readonly></p>
<p><label for="name">Name: </label>
<input id="name" type="text" value = {{ obj.name }} name="name"></p>
<p><label for="phonenumber">Phone Number: </label>
<input id="phonenumber" type="text" value = {{ obj.phonenumber }} name="phonenumber"></p>
<input type="submit" value="Update">
</form>
</body>
</html>
访问 URL http://localhost:8000/myapp/update/2 将呈现一个 HTML 表单,该表单预先填充了属于 pk=2 的数据。用户可以更新 name 和 phonenumber 字段。
Using ModelForm for Update
接下来,我们将使用 ModelForm 类呈现一个 HTML 表单,其 input 元素对应于模型字段类型。使用继承 Modelform 的 DereamrealForm 类
from django import forms
from .models import Dreamreal
class DreamrealForm(forms.ModelForm):
class Meta:
model = Dreamreal
fields = "__all__"
def __init__(self, *args, **kwargs):
super(DreamrealForm, self).__init__(*args, **kwargs)
self.fields['website'].widget = forms.TextInput(attrs={'readonly': 'readonly'})
self.fields['mail'].widget = forms.TextInput(attrs={'readonly': 'readonly'})
Note - 在这里,我们在类构造函数中设置了 website 和 mail 字段的只读属性。
视图函数 update() 从 URL 中接收主键参数,如同之前一样。当该函数使用 POST 方法调用时,表单数据将用于更新现有对象。
当使用 GET 方法时,Django 会抓取对应于主键的对象,并使用其属性填充 HTML 表单:
def update(request, pk):
obj = Dreamreal.objects.get(pk=pk)
if request.method == "POST":
form = DreamrealForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse("<h2>Record updated Successfully</h2>")
obj = Dreamreal.objects.get(pk=pk)
context = {"obj": DreamrealForm(instance=obj), "pk": obj.pk}
return render(request, "myform.html", context)
访问 http://localhost:8000/myapp/update/1 URL 以显示 HTML 表单,其字段已用 pk=1 的记录填充。您可以更改值,并提交对应的对象以进行更新。
The UpdateView Class
Django 定义了一组通用视图类。 UpdateView class 专门设计用于执行 INSERT 查询操作。
我们定义 UpdateView 类的子类,并将其 template_name 属性设置为我们已创建的 myform.html 。
将以下代码添加到 views.py 文件中−
from django.views.generic.edit import UpdateView
class DRUpdateView(UpdateView):
model = Dreamreal
fields = '__all__'
template_name = "myform.html"
success_url = "../success/"
为了注册此视图,我们需要为我们的应用更新 urls.py 文件。请注意,要注册通用视图,我们需要使用 as_view() 方法。
from django.urls import path
from . import views
from .views import DRCreateView, update, DRUpdateView
urlpatterns = [
path("", views.index, name="index"),
path("addnew/", views.addnew, name='addnew'),
path("add/", DRCreateView.as_view(), name='add'),
path("success/", views.success, name='success'),
path("update/<int:pk>", views.update, name='update'),
path("updateview/<int:pk>", views.update, name='update'),
]
我们不需要更改 myform.html 脚本,因为它将根据各个模型呈现 HTML 脚本。
访问 updateview/1 URL 以呈现预先填充了主键 = 1 的对象的表单。尝试更改一个或多个值并更新该表。