Django – 更新資料



Django ORM 使用活動記錄模式來處理模型類與其對映的資料庫表之間的互動。模型類的例項對應於表中的一行。物件的任何屬性都會導致相應行的更新。

在本章中,我們將重點介紹 Django 中更新關係資料庫中已存在行的不同方法。

我們將使用以下所示的Dreamreal 模型進行練習:

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)

假設您已經完成了遷移並向模型中添加了一些物件。

從 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() 方法,它可以獲取與給定關鍵字引數對應的單個例項:

obj = Dreamreal.objects.get(phonenumber = 2376970)

我們可以使用簡單的賦值來更新屬性。讓我們更改電話號碼:

obj.phonenumber = 24642367570

要使更改持久化,您需要呼叫save() 方法

obj.save()

透過呼叫檢視函式執行更新操作

現在讓我們透過呼叫檢視函式來執行更新操作。在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 https://:8000/myapp/update/2。瀏覽器將發出更新成功的訊息。

與其像上面示例中那樣使用硬編碼值,不如希望從使用者那裡接受資料。我們需要使用與主鍵對應的物件資料填充 HTML 表單。

修改 update() 檢視函式

修改 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 https://:8000/myapp/update/2 將呈現一個預填充了屬於 pk=2 的資料的 HTML 表單。使用者可以更新 name 和 phonenumber 欄位。

使用 ModelForm 進行更新

接下來,我們將使用 ModelForm 類來呈現一個 HTML 表單,其輸入元素對應於模型欄位型別。讓我們使用繼承 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'})

注意 - 在這裡,我們在類建構函式中設定了 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)

訪問https://:8000/myapp/update/1 URL 以顯示其欄位已填充 pk=1 記錄的 HTML 表單。您可以更改值並提交以更新相應的物件。

Django Update Data

UpdateView 類

Django 定義了一組通用檢視類。UpdateView 類專為執行 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 的物件的表單。嘗試更改一個或多個值並更新表。

廣告