自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(109)
  • 收藏
  • 关注

原创 python定时任务最强框架APScheduler详细教程

APScheduler定时任务上次测试女神听了我的建议,已经做好了要给项目添加定时任务的决定了。但是之前提供的四种方式中,她不知道具体选择哪一个。为了和女神更近一步,我把我入行近10年收藏的干货免费拿出来分享给女神,希望女神凌晨2点再找我的时候,不再是因为要给他调程序了。Python中定时任务的解决方案,总体来说有四种,分别是:crontab、 scheduler、 Celery、 APScheduler,其中 crontab不适合多台服务器的配置、scheduler太过于简单、 Celery依赖的软件

2020-05-29 15:48:03 7028 1

原创 Python定时任务实现的四种方案

昨晚凌晨两点,小编接到女神的电话,心里正心猿意马,没想到电话中的女神竟带着哭腔和我说老板让她现在就去公司加班,我很好奇的问她什么事情要这么晚去?女神委屈的说:“因为我们公司这个产品是针对美国用户,存在时差”说完又哭了起来。唉,小编心想终于有机会在女神面前露一手了,听我慢慢道来。在开发一个自动化测试平台,其中有一个功能是必不可少的,那就是定时任务调度。比如现在你的项目需要凌晨2点跑测试,你一个女孩子不可能真的2点钟起床跑到公司去执行测试吧,这时候定时任务就显得尤为重要,可以说是作为一个测试平台的标配了用

2020-05-29 15:38:38 1856

原创 图文并茂,详细讲解Git底层存储原理

自从小学妹学完定时任务后(详情请看上篇文章),对我那是百般仰慕,遇到问题第一时间就会想到我(是的,要的就是这种效果)。这不,小学妹今天又找我了,今天的问题是什么呢?听我细细道来…原来小学妹在公司中,用的是 Git的代码管理工具(还不知道这个软件的要面壁啦~)。有一天不知道发生什么了,文件夹中所有代码都被删掉了,但是只留下本地一个 .git文件夹,这可把小学妹急坏了,刚写完一个大功能,还没来得急提交到远程服务器,明天就要开始内测了,重写已经来不及了…听完小学妹的诉求后,我慢悠悠的跟她说:小事儿一桩,交给学

2020-05-29 14:59:00 712

原创 一台电脑如何同时玩转GitHub和公司Git服务器?

最近有个小学妹刚入职新公司,公司用的是Git版本管理工具,然后她其实自己也经常玩Github,Git用起来基本操作也不大。但是现在她遇到一个小问题,相信这个问题很多程序员(媛)也经常遇到。什么问题呢?来跟大家唠一唠。大家都知道,在多人协作开发中,我们需要把代码提交到Git服务器的。但是并不是所有人都可以往服务器上推送代码,只有有相应权限的人才能推送,所以就涉及到如何对服务器进行授权的问题。现在授权方式有两种,一种是HTTP/HTTPS协议,另外一种是SSH Key协议。HTTP/HTTPS协议好处是方便

2020-05-19 10:42:26 450

原创 最浅显易懂的Django系列教程(20)-查询操作

查询操作查找是数据库操作中一个非常重要的技术。查询一般就是使用filter、exclude以及get三个方法来实现。我们可以在调用这些方法的时候传递不同的参数来实现查询需求。在ORM层面,这些查询条件都是使用field+__+condition的方式来使用的。以下将那些常用的查询条件来一一解释。查询条件exact:使用精确的=进行查找。如果提供的是一个None,那么在SQL层面就是被解释为NULL。示例代码如下:article = Article.objects.get(id__exact=14)

2020-05-18 10:39:01 622

原创 最浅显易懂的Django系列教程(49)-redis教程

redis教程:概述redis是一种nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,并且他比memcached支持更多的数据结构(string,list列表[队列和栈],set[集合],sorted set[有序集合],hash(hash表))。相关参考文档:http://redisdoc.com/index.htmlredis使用场景:登录会话存储:存储在redis中,与memcached相比,数据不会丢失。排行版/计数器:比如一些秀场

2020-05-14 15:46:05 519

原创 最浅显易懂的Django系列教程(48)-memcached

memcached什么是memcached:memcached之前是danga的一个项目,最早是为LiveJournal服务的,当初设计师为了加速LiveJournal访问速度而开发的,后来被很多大型项目采用。官网是www.danga.com或者是memcached.org。Memcached是一个高性能的分布式的内存对象缓存系统,全世界有不少公司采用这个缓存项目来构建大负载的网站,来分担数据库的压力。Memcached是通过在内存里维护一个统一的巨大的hash表,memcached能存储各种各样的

2020-05-14 15:44:31 195

原创 最浅显易懂的Django系列教程(47)-权限和分组

权限和分组登录、注销和登录限制:登录在使用authenticate进行验证后,如果验证通过了。那么会返回一个user对象,拿到user对象后,可以使用django.contrib.auth.login进行登录。示例代码如下:user = authenticate(username=username, password=password)if user is not None: if user.is_active: login(request, user)注销:注销,或

2020-05-14 15:42:30 304

原创 最浅显易懂的Django系列教程(46)-用户对象

User模型User模型是这个框架的核心部分。他的完整的路径是在django.contrib.auth.models.User。以下对这个User对象做一个简单了解:字段:内置的User模型拥有以下的字段:username: 用户名。150个字符以内。可以包含数字和英文字符,以及_、@、+、.和-字符。不能为空,且必须唯一!first_name:歪果仁的first_name,在30个字符以内。可以为空。last_name:歪果仁的last_name,在150个字符以内。可以为空。email:

2020-05-14 15:40:15 225

原创 最浅显易懂的Django系列教程(45)-概述

验证和授权概述Django有一个内置的授权系统。他用来处理用户、分组、权限以及基于cookie的会话系统。Django的授权系统包括验证和授权两个部分。验证是验证这个用户是否是他声称的人(比如用户名和密码验证,角色验证),授权是给与他相应的权限。Django内置的权限系统包括以下方面:用户。权限。分组。一个可以配置的密码哈希系统。一个可插拔的后台管理系统。使用授权系统:默认中创建完一个django项目后,其实就已经集成了授权系统。那哪些部分是跟授权系统相关的配置呢。以下做一个简单列表:

2020-05-14 15:38:25 266

原创 最浅显易懂的Django系列教程(44)-注入SQL

SQL注入所谓SQL注入,就是通过把SQL命令插入到表单中或页面请求的查询字符串中,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的。场景:比如现在数据库中有一个front_user表,表结构如下:class User(m

2020-05-14 14:52:09 327 1

原创 最浅显易懂的Django系列教程(43)-点击劫持攻击

clickjacking攻击:clickjacking攻击又称作点击劫持攻击。是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段。clickjacking攻击场景:场景一:如用户收到一封包含一段视频的电子邮件,但其中的“播放”按钮并不会真正播放视频,而是链入一购物网站。这样当用户试图“播放视频”时,实际是被诱骗而进入了一个购物网站。场景二:用户进入到一个网页中,里面包含了一个非常有诱惑力的按钮A,但是这个按钮上面浮了一个透明的iframe标签,这个iframe标签

2020-05-14 14:51:13 401

原创 最浅显易懂的Django系列教程(42)-XSS攻击

XSS攻击XSS(Cross Site Script)攻击又叫做跨站脚本攻击。他的原理是用户在使用具有XSS漏洞的网站的时候,向这个网站提交一些恶意的代码,当用户在访问这个网站的某个页面的时候,这个恶意的代码就会被执行,从而来破坏网页的结构,获取用户的隐私信息等。XSS攻击场景:比如A网站有一个发布帖子的入口,如果用户在提交数据的时候,提交了一段js代码比如:<script>alert("hello world");</script>,然后A网站在渲染这个帖子的时候,直接把这个

2020-05-14 14:50:23 390

原创 最浅显易懂的Django系列教程(41)-CSRF攻击

CSRF攻击:CSRF攻击概述:CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一。其他安全隐患,比如 SQL 脚本注入,跨站域脚本攻击等在近年来已经逐渐为众人熟知,很多网站也都针对他们进行了防御。然而,对于大多数人来说,CSRF 却依然是一个陌生的概念。即便是大名鼎鼎的 Gmail, 在 2007 年底也存在着 CSRF 漏洞,从而被黑客攻击而使 Gmail 的用户造成巨大的损失。CSRF攻击

2020-05-14 14:49:42 240

原创 最浅显易懂的Django系列教程(40)-中间件

中间件中间件是在request和response处理过程中的一个插件。比如在request到达视图函数之前,我们可以使用中间件来做一些相关的事情,比如可以判断当前这个用户有没有登录,如果登录了,就绑定一个user对象到request上。也可以在response到达浏览器之前,做一些相关的处理,比如想要统一在response上设置一些cookie信息等。自定义中间件:中间件所处的位置没有规定。只要是放到项目当中即可。一般分为两种情况,如果中间件是属于某个app的,那么可以在这个app下面创建一个pyth

2020-05-14 14:48:43 195

原创 最浅显易懂的Django系列教程(39)-上下文处理器

上下文处理器上下文处理器是可以返回一些数据,在全局模板中都可以使用。比如登录后的用户信息,在很多页面中都需要使用,那么我们可以放在上下文处理器中,就没有必要在每个视图函数中都返回这个对象。在settings.TEMPLATES.OPTIONS.context_processors中,有许多内置的上下文处理器。这些上下文处理器的作用如下:django.template.context_processors.debug:增加一个debug和sql_queries变量。在模板中可以通过他来查看到一些数据库

2020-05-14 14:48:01 211

原创 最浅显易懂的Django系列教程(38)-cookie和session

cookie和sessioncookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过

2020-05-14 14:47:15 191

原创 最浅显易懂的Django系列教程(37)-文件上传

文件上传:文件上传是网站开发中非常常见的功能。这里详细讲述如何在Django中实现文件的上传功能。前端HTML代码实现:在前端中,我们需要填入一个form标签,然后在这个form标签中指定enctype="multipart/form-data",不然就不能上传文件。在form标签中添加一个input标签,然后指定input标签的name,以及type="file"。以上两步的示例代码如下:<form action="" method="post" enctype="multipart

2020-05-14 14:44:35 263

原创 最浅显易懂的Django系列教程(36)-ModelForm

ModelForm:大家在写表单的时候,会发现表单中的Field和模型中的Field基本上是一模一样的,而且表单中需要验证的数据,也就是我们模型中需要保存的。那么这时候我们就可以将模型中的字段和表单中的字段进行绑定。比如现在有个Article的模型。示例代码如下:from django.db import modelsfrom django.core import validatorsclass Article(models.Model): title = models.CharField

2020-05-14 14:43:57 291

原创 最浅显易懂的Django系列教程(35)-用表单验证数据

用表单验证数据常用的Field:使用Field可以是对数据验证的第一步。你期望这个提交上来的数据是什么类型,那么就使用什么类型的Field。CharField:用来接收文本。参数:max_length:这个字段值的最大长度。min_length:这个字段值的最小长度。required:这个字段是否是必须的。默认是必须的。error_messages:在某个条件验证失败的时候,给出错误信息。EmailField:用来接收邮件,会自动验证邮件是否合法。错误信息的key:require

2020-05-14 14:42:44 281

原创 最浅显易懂的Django系列教程(34)-表单概述

表单:HTML中的表单:单纯从前端的html来说,表单是用来提交数据给服务器的,不管后台的服务器用的是Django还是PHP语言还是其他语言。只要把input标签放在form标签中,然后再添加一个提交按钮,那么以后点击提交按钮,就可以将input标签中对应的值提交给服务器了。Django中的表单:Django中的表单丰富了传统的HTML语言中的表单。在Django中的表单,主要做以下两件事:渲染表单模板。表单验证数据是否合法。Django中表单使用流程:在讲解Django表单的具体每部分

2020-05-14 14:41:59 253

原创 最浅显易懂的Django系列教程(33)-分页

分页在Django中实现分页功能非常简单。因为Django已经内置了两个处理分类的类。分别是Paginator和Page。Paginator用来管理整个分类的一些属性,Page用来管理当前这个分页的一些属性。通过这两个类,就可以轻松的实现分页效果。以下对这两个类进行讲解。Paginator类:Paginator是用来控制整个分页的逻辑的。比如总共有多少页,页码区间等等。都可以从他上面来获取。创建Paginator对象:class Paginator(object_list, per_page, o

2020-05-14 14:41:03 204

原创 最浅显易懂的Django系列教程(32)-错误处理

错误处理在一些网站开发中。经常会需要捕获一些错误,然后将这些错误返回比较优美的界面,或者是将这个错误的请求做一些日志保存。那么我们本节就来讲讲如何实现。常用的错误码:404:服务器没有指定的url。403:没有权限访问相关的数据。405:请求的method错误。400:bad request,请求的参数错误。500:服务器内部错误,一般是代码出bug了。502:一般部署的时候见得比较多,一般是nginx启动了,然后uwsgi有问题。自定义错误模板:在碰到比如404,500错误的时候,

2020-05-14 14:40:19 229

原创 最浅显易懂的Django系列教程(31)-类视图

类视图在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图。使用类视图可以使用类的一些特性,比如继承等。View:django.views.generic.base.View是主要的类视图,所有的类视图都是继承自他。如果我们写自己的类视图,也可以继承自他。然后再根据当前请求的method,来实现不同的方法。比如这个视图只能使用get的方式来请求,那么就可以在这个类中定义get(self,request,*args,**kwargs)方法。以此类推,如果只需要实现post方法,那么就只

2020-05-14 14:39:20 220

原创 最浅显易懂的Django系列教程(30)-生成CSV文件

生成CSV文件:有时候我们做的网站,需要将一些数据,生成有一个CSV文件给浏览器,并且是作为附件的形式下载下来。以下将讲解如何生成CSV文件。生成小的CSV文件:这里将用一个生成小的CSV文件为例,来把生成CSV文件的技术要点讲到位。我们用Python内置的csv模块来处理csv文件,并且使用HttpResponse来将csv文件返回回去。示例代码如下:import csvfrom django.http import HttpResponsedef csv_view(request):

2020-05-14 14:38:31 289

原创 最浅显易懂的Django系列教程(29)-httpresponse对象

HttpResponse对象Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数。那么视图函数在处理完相关的逻辑后,也需要返回一个响应给浏览器。而这个响应,我们必须返回HttpResponseBase或者他的子类的对象。而HttpResponse则是HttpResponseBase用得最多的子类。那么接下来就来介绍一下HttpResponse及其子类。常用属性:content:返回的内容。status_code:返回的HTTP响应状

2020-05-14 14:37:43 284

原创 最浅显易懂的Django系列教程(28)-httprequest对象

WSGIRequest对象Django在接收到http请求之后,会根据http请求携带的参数以及报文信息创建一个WSGIRequest对象,并且作为视图函数第一个参数传给视图函数。也就是我们经常看到的request参数。在这个对象上我们可以找到客户端上传上来的所有信息。这个对象的完整路径是django.core.handlers.wsgi.WSGIRequest。WSGIRequest对象常用属性和方法:WSGIRequest对象常用属性:WSGIRequest对象上大部分的属性都是只读的。因为这些

2020-05-14 14:35:59 200

原创 最浅显易懂的Django系列教程(27)-页面重定向

重定向重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。

2020-05-14 14:34:29 288

原创 最浅显易懂的Django系列教程(26)-限制请求method

Django限制请求method常用的请求method:GET请求:GET请求一般用来向服务器索取数据,但不会向服务器提交数据,不会对服务器的状态进行更改。比如向服务器获取某篇文章的详情。POST请求:POST请求一般是用来向服务器提交数据,会对服务器的状态进行更改。比如提交一篇文章给服务器。限制请求装饰器:Django内置的视图装饰器可以给视图提供一些限制。比如这个视图只能通过GET的method访问等。以下将介绍一些常用的内置视图装饰器。django.http.decorators.

2020-05-14 14:33:43 179

原创 最浅显易懂的Django系列教程(25)-Pycharm连接数据库

Pycharm配置连接数据库进入pycharm后,右边有一个Database的选项,点击这个选项会弹出以下界面:然后点击绿色的添加按钮,会出现以下界面:这时候我们选择MySQL,然后会弹出以下配置MySQL的对话框填入相关的信息。然后Test Connection测试成功后,点击确定即可!关于没有Java Connector Driver:Pycharm是用java写的,连接MySQL数据库需要一个driver文件,从以下链接中下载mysql-connector-java-5.1.46.

2020-05-14 14:32:56 257

原创 最浅显易懂的Django系列教程(24)-ORM作业参考答案

ORM作业参考答案:查询平均成绩大于60分的同学的id和平均成绩; rows = Student.objects.annotate(avg=Avg("score__number")).filter(avg__gte=60).values("id","avg") for row in rows: print(row)查询所有同学的id、姓名、选课的数、总成绩; rows = Student.objects.annotate(course_nums=Count("score__co

2020-05-14 14:28:48 317

原创 最浅显易懂的Django系列教程(23)-ORM作业

ORM作业:假设有以下ORM模型:from django.db import modelsclass Student(models.Model): """学生表""" name = models.CharField(max_length=100) gender = models.SmallIntegerField() class Meta: db_table = 'student'class Course(models.Model): "

2020-05-14 14:26:48 191

原创 最浅显易懂的Django系列教程(22)-ORM模型迁移

ORM模型迁移迁移命令:makemigrations:将模型生成迁移脚本。模型所在的app,必须放在settings.py中的INSTALLED_APPS中。这个命令有以下几个常用选项:app_label:后面可以跟一个或者多个app,那么就只会针对这几个app生成迁移脚本。如果没有任何的app_label,那么会检查INSTALLED_APPS中所有的app下的模型,针对每一个app都生成响应的迁移脚本。–name:给这个迁移脚本指定一个名字。–empty:生成一个空的迁移脚本。如果你想写

2020-05-14 14:22:48 329

原创 最浅显易懂的Django系列教程(21)-QuerySet API

QuerySet API:我们通常做查询操作的时候,都是通过模型名字.objects的方式进行操作。其实模型名字.objects是一个django.db.models.manager.Manager对象,而Manager这个类是一个“空壳”的类,他本身是没有任何的属性和方法的。他的方法全部都是通过Python动态添加的方式,从QuerySet类中拷贝过来的。示例图如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SPeDlopA-1589436455513)(/asse

2020-05-14 14:16:22 409

原创 最浅显易懂的Django系列教程(19)-增删改查操作

模型的操作:在ORM框架中,所有模型相关的操作,比如添加/删除等。其实都是映射到数据库中一条数据的操作。因此模型操作也就是数据库表中数据的操作。添加一个模型到数据库中:添加模型到数据库中。首先需要创建一个模型。创建模型的方式很简单,就跟创建普通的Python对象是一摸一样的。在创建完模型之后,需要调用模型的save方法,这样Django会自动的将这个模型转换成sql语句,然后存储到数据库中。示例代码如下:class Book(models.Model): name = models.Char

2020-05-14 14:07:07 257

原创 最浅显易懂的Django系列教程(18)-表关系和外键

外键和表关系外键:在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam。如果使用的是InnoDB引擎,是支持外键约束的。外键的存在使得ORM框架在处理表关系的时候异常的强大。因此这里我们首先来介绍下外键在Django中的使用。类定义为class ForeignKey(to,on_delete,**options)。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有CASCADE、SET_NULL等。这里以一个实际案例来说明。比如有

2020-05-14 14:06:01 245

原创 最浅显易懂的Django系列教程(17)-模型常用字段

模型常用属性常用字段:在Django中,定义了一些Field来与数据库表中的字段类型来进行映射。以下将介绍那些常用的字段类型。AutoField:映射到数据库中是int类型,可以有自动增长的特性。一般不需要使用这个类型,如果不指定主键,那么模型会自动的生成一个叫做id的自动增长的主键。如果你想指定一个其他名字的并且具有自动增长的主键,使用AutoField也是可以的。BigAutoField:64位的整形,类似于AutoField,只不过是产生的数据的范围是从1-9223372036854775

2020-05-14 13:59:30 151

原创 最浅显易懂的Django系列教程(16)-ORM模型

ORM模型介绍随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了:SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长。会出现很多相近的SQL语句。很多SQL语句是在业务逻辑中拼出来的,如果有数据库需要更改,就要去修改这些逻辑,这会很容易漏掉对某些SQL语句的修改。写SQL时容易忽略web安全问题,给未来造成隐患。SQL注入。ORM,全称Object Relational Mapping,中文叫做对象关系映射,通过ORM我们可以通过类的方式去操作

2020-05-14 13:52:50 183

原创 最浅显易懂的Django系列教程(15)-数据库操作

操作数据库Django配置连接数据库:在操作数据库之前,首先先要连接数据库。这里我们以配置MySQL为例来讲解。Django连接数据库,不需要单独的创建一个连接对象。只需要在settings.py文件中做好数据库相关的配置就可以了。示例代码如下:DATABASES = { 'default': { # 数据库引擎(是mysql还是oracle等) 'ENGINE': 'django.db.backends.mysql', # 数据库的名字

2020-05-14 13:49:54 298

原创 最浅显易懂的Django系列教程(14)-MySQL相关软件

MySQL数据库在网站开发中,数据库是网站的重要组成部分。只有提供数据库,数据才能够动态的展示,而不是在网页中显示一个静态的页面。数据库有很多,比如有SQL Server、Oracle、PostgreSQL以及MySQL等等。MySQL由于价格实惠、简单易用、不受平台限制、灵活度高等特性,目前已经取得了绝大多数的市场份额。因此我们在Django中,也是使用MySQL来作为数据存储。MySQL数据库安装:在MySQL的官网下载MySQL数据库安装文件:https://dev.mysql.com/do

2020-05-14 13:45:30 281

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除