Django 简明教程

Django – Delete Data

Django ORM 是 Django 框架的一项重要功能。它是模型类与其映射的数据库表之间交互的抽象层。模型类的实例对应于表中的一行。我们可以在对象上执行所有 CRUD 操作;它会自动反映在其映射的行中。

Django ORM is an important feature of Django framework. It is an abstract layer for the interaction between a model class and its mapped database table. An instance of the model class corresponds to a single row in the table. We can perform all the CRUD operations on the object; it will be automatically reflected in its mapped row.

在本章中,我们将介绍如何删除一个对象,从而在一个关系数据库中删除一行已经存在的行。

In this chapter, we shall find out how we can delete an object and thereby an already existing row in a relational database.

我们将使用下面给出的 Dreamreal model 作为本次练习:

We shall use the Dreamreal model as given below for the exercise −

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)

假设您已经执行了迁移,并在模型中添加了一些对象。

It is assumed that you have already performed the migrations and added a few objects in the model.

Delete Object From Shell

Django 有一项有用的功能,您可以用它在 Django 项目的环境中调用 Python Shell。

Django has a useful feature with which you can invoke a Python shell inside the Django project’s environment.

使用带有 manage.py 脚本的 shell command

Use the shell command with the manage.py script −

python manage.py shell

在 Python 提示符之前,导入 Dreamreal model

In front of the Python prompt, import the Dreamreal model

>>> from myapp.models import Dreamreal

您可以使用 delete() method 从模型中删除一个或多个对象。此方法可以应用于包含多个对象的 QuerySet,也可以应用于单个实例。

You can delete one or more objects from the model with the delete() method. This method can be applied on the QuerySet that consists of more than one objects, or on a single instance.

要删除单个对象,请从 objects() 管理器的 get() method 中的模型中进行删除:

To delete a single object, do it from the model with get() method of the objects() manager −

row = Dreamreal.objects.get(pk = 1)

您现在可以调用 delete() method

You can now invoke the delete() method

row.delete()

以下语句返回一个 QuerySet,其中对象的名称以 a 开始:

The following statement returns a QuerySet of objects with name starting with "a" −

rows = Dreamreal.objects.filter(name__startswith = 'a')

您可以通过调用 queryset 上的 delete() 方法来执行批量删除操作:

You can perform bulk delete operation by calling delete() method on the queryset −

rows.delete()

Django 返回已删除的对象数和一个字典,其中包含每种对象类型的删除数。

Django returns the number of objects deleted and a dictionary with the number of deletions per object type.

对于相关表,Django 的 ForeignKey 默认模拟 SQL 约束 ON DELETE CASCADE。换句话说,任何具有指向要删除的对象的外键的对象将与其一起被删除。

In case of related tables, Django’s ForeignKey emulates the SQL constraint ON DELETE CASCADE by default. In other words, any objects with foreign keys pointing at the objects to be deleted will be deleted along with them.

Perform Delete Operation by Calling a View Function

现在,让我们通过调用视图函数来执行删除操作。在 views.py 文件中定义 update() 函数。

Let us now perform the delete operation by calling a view function. Define update() function in views.py file.

此函数从其映射的 URL 中接收主键作为参数。

This function receives the primary key as the argument from its mapped URL.

from django.shortcuts import render
from django.http import HttpResponse
from myapp.models import Dreamreal

def delete(request, pk):
   obj = Dreamreal.objects.get(pk=pk)
   obj.delete()
   return HttpResponse("Deleted successfully")

我们还需要在 urls.py 文件中注册此视图,方法是添加一条新路径。

We also need to register this view in the urls.py file by adding a new path.

urlpatterns + = [path("delete/<int:pk>", views.delete, name='delete')]

进行这些更改后,运行 Django 服务器并访问 http://localhost:8000/myapp/delete/2 。服务器将以删除成功的消息进行响应。

After making these changes, run Django server and visit http://localhost:8000/myapp/delete/2. The server responds with the deleted successfully message.

如果您想访问具有给定名称而不是主键的对象,请对 delete() view 中的内容进行以下更改:

If you would like to access an object with a given name instead of primary key, make changes in the delete() view as follows −

def delete(request, name):
   obj = Dreamreal.objects.get(name=name)
   obj.delete()
   return HttpResponse("Deleted successfully")

同时更改 myapp 的 URLCONFIG 中 delete() 视图的 URL 映射−

Also change the URL mapping of the delete() view in URLCONFIG of myapp −

urlpatterns + = [path("delete/<name>", views.delete, name='delete')]

delete 操作必须谨慎执行,因为您可能会意外删除您不想删除的数据。因此,我们可以向用户索要确认。为此目的,delete() 视图会呈现一个带有提交和取消按钮的表单。

The delete operation must be carried out with caution, as you can accidentally delete data that you don’t intend to. Hence, we can ask a confirmation from the user. For this purpose, the delete() view renders a form with submit and cancel buttons.

def delete(request, pk):
   obj = Dreamreal.objects.get(pk=pk)
   if request.method == "POST":
      obj.delete()
      obj.save()
      return HttpResponse("<h2>Record updated Successfully</h2>")
   obj = Dreamreal.objects.get(pk=pk)
   context = {"pk":pk}
   return render(request, "myform.html", context)

模板文件夹中的 myform.html 有两个按钮。 submit button 会将数据反馈发布到 delete() 视图,并在该对象上调用 delete() 方法−

The myform.html in templates folder has two buttons. The submit button posts back to delete() view, and calls the delete() method on the object −

<html>
<body>
   <form action="../delete/{{ pk }}" method="post">
      {% csrf_token %}
      <h2>The record with primary {{ pk }} will be deleted. Are you sure?</h2>
      <input type="submit" value="delete">
      <a href = "../cancel"><input type="button" value="Cancel" /></a>
   </form>
</body>
</html>

将 cancel() 视图添加如下−

Add the cancel() view as follows −

def cancel(request):
   return HttpResponse("<h2>Delete operation Cancelled by the user</h2>")
django delete data 1

如果用户按下取消按钮, cancel() view 会显示此消息−

If the user presses the Cancel button, the cancel() view displays this message −

django delete data 2

否则,该记录将从表中删除。

Otherwise, the record will be deleted from the table.

The DeleteView Class

Django 定义了一系列通用视图类。DeleteView 类是专门为执行 DELETE 查询操作而设计的。

Django defines a collection of generic view classes. The DeleteView class is specially designed for performing the DELETE query operation.

我们定义 DeleteView 类的子类,并设置其 template_name 属性为我们已创建的 myform.html

We define a subclass of DeleteView class, and set its template_name property to myform.html that we have already created.

将以下代码添加到 views.py 文件中−

Add the following code in views.py file −

from django.views.generic.edit import DeleteView
class DRDeleteView(DeleteView):
   model = Dreamreal
   template_name = "myform.html"
   success_url = "../success/"

myform.html 文件保持不变−

The myform.html file remains the same −

<html>
<body>
   <form method="post">
      {% csrf_token %}
      <h2>The record will be deleted. Are you sure?</h2>
      <input type="submit" value="delete">
      <a href = "../cancel">
      <input type="button" value="Cancel" /></a>
   </form>
</body>
</html>

将映射添加到 urls.py 文件中的 DeleteView 通用类中−

Add the mapping to the DeleteView generic class in urls.py file −

from .views import DRDeleteView
urlpatterns += [path("deleteview/<int:pk>", DRDeleteView.as_view(), name='deleteview')]

通过访问 http://localhost:8000/myapp/deleteview/2 URL 检查所需的记录是否已删除。

Check that the desired record is deleted by visiting http://localhost:8000/myapp/deleteview/2 URL.

在本章中,我们解释了如何使用不同方法从 Django 模型中删除数据。

In this chapter, we explained how you can delete data from Django model using different methods.