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 的记录填充。您可以更改值,并提交对应的对象以进行更新。

django update data

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 的对象的表单。尝试更改一个或多个值并更新该表。